using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.Tracing; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Numerics; using System.Numerics.Hashing; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Concentus; using Concentus.Celt; using Concentus.Celt.Structs; using Concentus.Common; using Concentus.Common.CPlusPlus; using Concentus.Enums; using Concentus.Native; using Concentus.Oggfile; using Concentus.Silk; using Concentus.Silk.Enums; using Concentus.Silk.Structs; using Concentus.Structs; using FxResources.System.Buffers; using FxResources.System.Memory; using FxResources.System.Numerics.Vectors; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalConfig; using LethalConfig.ConfigItems; using LethalNetworkAPI; using LethalNetworkAPI.Utils; using Microsoft.CodeAnalysis; using Microsoft.Win32.SafeHandles; using TTSCompany.Components; using TTSCompany.Components.Constants; using TTSCompany.Components.Enums; using TTSCompany.Components.Helpers; using TTSCompany.Components.Managers; using TTSCompany.Components.Managers.Components; using TTSCompany.Components.Networking; using TTSCompany.Components.Networking.Components; using TTSCompany.Components.Networking.Components.Structs; using TTSCompany.Components.Server.Components; using TTSCompany.Debug; using TTSCompany.Debug.Inputs; using TTSCompany.Patches; using Unity.Netcode; using UnityEngine; using UnityEngine.Audio; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TTS-Company")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("PixelIndieDev")] [assembly: AssemblyProduct("TTS-Company")] [assembly: AssemblyCopyright("Copyright © 2026 PixelIndieDev")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("11e971ee-3d73-490e-bf46-c90ae5be06a2")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace TTSCompany { internal static class ModInfo { internal const string modGUID = "PixelIndieDev_TTSCompany"; internal const string modName = "TTS Company"; internal const string modVersion = "1.0.0.0"; } [BepInPlugin("PixelIndieDev_TTSCompany", "TTS Company", "1.0.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class TTSCompanyPlugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("PixelIndieDev_TTSCompany"); internal static TTSGenerator _tts; internal static TTSCompanyDebugInputs inputActionsInstance; internal static ConfigEntry configEntryPriority; internal static ConfigEntry configEntryTimeoutBuffer; internal static ConfigEntry configEntryClearCacheOnExit; internal static ConfigEntry configEntryClearCacheManually; private bool _isDeletingCache; private bool _isShuttingDown; private bool _shutdownComplete; internal static TTSCompanyPlugin instance { get; private set; } internal static bool IsInputUtilsPresent { get; private set; } internal static TTSPlaybackManager _ttsPlaybackManagerObject { get; private set; } private void Awake() { //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; if ((Object)(object)instance == (Object)null) { instance = this; } Application.wantsToQuit += OnWantsToQuit; IsInputUtilsPresent = Chainloader.PluginInfos.ContainsKey("com.rune580.LethalCompanyInputUtils"); if (IsInputUtilsPresent) { inputActionsInstance = new TTSCompanyDebugInputs(); inputActionsInstance.PixelIndieDev_TestTTS_01.performed += DebugManualTrigger.TriggerTestTTS01; inputActionsInstance.PixelIndieDev_TestTTS_02.performed += DebugManualTrigger.TriggerTestTTS02; } _tts = new TTSGenerator(); configEntryPriority = ((BaseUnityPlugin)this).Config.Bind("TTS Generation", "TTS generation priority", TTSGenPriority.Normal, "Adjusts the CPU priority for generating TTS. Higher priority may increase the TTS generation speed at the cost of performance."); configEntryPriority.SettingChanged += delegate { _tts.SetMaxConcurrentRequests(configEntryPriority.Value); }; LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem(configEntryPriority, false)); configEntryTimeoutBuffer = ((BaseUnityPlugin)this).Config.Bind("TTS Generation", "TTS timeout scaling", TimeoutBufferScaling.Normal, "Controls how long the mod waits for a voice line to generate. Increase this if your TTS audio keeps getting cut off, or decrease it if you want the mod to give up faster when experiencing delays. \n\nControlled by the host."); configEntryTimeoutBuffer.SettingChanged += delegate { TTSConstants.UpdateTimeoutBuffers(); }; LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem(configEntryTimeoutBuffer, false)); configEntryClearCacheOnExit = ((BaseUnityPlugin)this).Config.Bind("Cache", "Clear TTS cache on exit", false, "When enabled, automatically deletes saved TTS cache when you close Lethal Company. Disabling this saves disk space but requires files to be regenerate next session."); LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(configEntryClearCacheOnExit, false)); configEntryClearCacheManually = ((BaseUnityPlugin)this).Config.Bind("Cache", "Clear TTS cache now", false, "Check this checkbox to delete all saved local TTS cache. \n\nBest done in the main menu."); configEntryClearCacheManually.SettingChanged += delegate { if (!_isDeletingCache) { ClearTTSCache(); } configEntryClearCacheManually.Value = false; }; LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(configEntryClearCacheManually, false)); _tts.SetMaxConcurrentRequests(configEntryPriority.Value); TTSConstants.UpdateTimeoutBuffers(); GameObject val = new GameObject("TTSPlaybackManager"); _ttsPlaybackManagerObject = val.AddComponent(); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)val); harmony.PatchAll(typeof(StartOfRoundPatch)); harmony.PatchAll(typeof(GameNetworkManagerPatch)); TTSCompanyNetworking.Initialize(); OnAwake(); LogConstants.PLUGIN_LOADED.Log("TTSCompanyPlugin", "TTS Company", "1.0.0.0"); } private async void OnAwake() { if (!(await _tts.InitializeAsync())) { LogConstants.PLUGIN_TTS_COULD_NOT_BE_INITIALIZED.Log("TTSCompanyPlugin", "new TTSGenerator()"); } await TTSCompanyAPI.PreloadTTSVoiceModelInMemory("en_US-hfc_female-medium"); await TTSCompanyAPI.PreloadTTSVoiceModelInMemory("en_US-hfc_male-medium"); await TTSCompanyAPI.PreloadTTSVoiceModelInMemory("en_US-ryan-medium"); await TTSCompanyAPI.PreloadTTSVoiceModelInMemory("en_US-sam-medium"); } private void ClearTTSCache() { _isDeletingCache = true; if (Directory.Exists(TTSConstants.TTS_VOICE_CACHE_SOUNDCLIPS_PATH)) { try { Directory.Delete(TTSConstants.TTS_VOICE_CACHE_SOUNDCLIPS_PATH, recursive: true); } catch (IOException) { LogConstants.CODE_GENERIC_CATCH.Log("TTSCompanyPlugin", "ClearTTSCache"); } } _isDeletingCache = false; } private bool OnWantsToQuit() { if (_shutdownComplete) { return true; } if (_isShuttingDown) { return false; } _isShuttingDown = true; ExecuteAsyncShutdown(); return false; } private async void ExecuteAsyncShutdown() { LogConstants.PLUGIN_ON_QUIT.Log("TTSCompanyPlugin", "TTS Company", "1.0.0.0"); if (configEntryClearCacheOnExit.Value) { ClearTTSCache(); } try { if (_tts != null) { LogConstants.CODE_TRIGGERED.Log("TTSCompanyPlugin", "ExecuteAsyncShutdown"); await _tts.ShutdownAsync(); } } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyPlugin", "ExecuteAsyncShutdown", ex.Message); } finally { _shutdownComplete = true; if (_tts != null) { _tts.Dispose(); } Application.Quit(); } } private void OnDisable() { if (!_isShuttingDown && _tts != null) { _tts.Dispose(); } } private void OnDestroy() { if (!_isShuttingDown && _tts != null) { _tts.Dispose(); } } } public static class TTSCompanyAPI { private static readonly PiperVoiceSettings DefaultVoiceSettings = new PiperVoiceSettings(); private static readonly TTSAudioSourceSettings DefaultTTSAudioSourceSettings = new TTSAudioSourceSettings(); [MethodImpl(MethodImplOptions.NoInlining)] public static async Task<(bool Success, string Error)> PreloadTTSVoiceModelInMemory(string voiceModelName) { voiceModelName = VoiceHelper.CleanupVoiceModelname(voiceModelName); LogConstants.API_TRIGGER_PRELOAD_VOICE_MODEL.Log("TTSCompanyAPI", voiceModelName); ulong callingAssemblyHash = HashHelper.GetCallingAssemblyHash(Assembly.GetCallingAssembly()); return await TTSCompanyPlugin._tts.PreloadVoiceAsync(voiceModelName, callingAssemblyHash); } [MethodImpl(MethodImplOptions.NoInlining)] public static async Task<(bool Success, string Error)> UnloadTTSVoiceModelInMemory(string voiceModelName) { voiceModelName = VoiceHelper.CleanupVoiceModelname(voiceModelName); LogConstants.API_TRIGGER_UNLOAD_VOICE_MODEL.Log("TTSCompanyAPI", voiceModelName); ulong callingAssemblyHash = HashHelper.GetCallingAssemblyHash(Assembly.GetCallingAssembly()); return await TTSCompanyPlugin._tts.UnloadVoiceAsync(voiceModelName, callingAssemblyHash); } [MethodImpl(MethodImplOptions.NoInlining)] public static void AddTTSAudioSourceOnNetworkObject(GameObject objectRefOfSpeaker, bool useGlobalAudioSource = true, TTSAudioSourceSettings audioSourceSettings = null) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (objectRefOfSpeaker.TryGetComponent(ref val)) { TTSCompanyAPI.AddTTSAudioSourceOnNetworkObject(new NetworkObjectReference(val), useGlobalAudioSource, audioSourceSettings); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void AddTTSAudioSourceOnNetworkObject(NetworkObjectReference networkObjectRefOfSpeaker, bool useGlobalAudioSource = true, TTSAudioSourceSettings audioSourceSettings = null) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) audioSourceSettings = audioSourceSettings ?? DefaultTTSAudioSourceSettings; ulong callingAssemblyHash = (useGlobalAudioSource ? HashHelper.GlobalCallerHash : HashHelper.GetCallingAssemblyHash(Assembly.GetCallingAssembly())); NetworkObject val = default(NetworkObject); if (LNetworkUtils.IsConnected) { TTSCompanyNetworking.Request_Server_SpawnTTSSource(new SpawnTTSAudioSource_NET(networkObjectRefOfSpeaker, callingAssemblyHash, audioSourceSettings)); } else if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", networkObjectRefOfSpeaker); } else { TTSAudioSourceManager.AddPermanentTTSAudioSource(((Component)val).gameObject, callingAssemblyHash, audioSourceSettings); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void RemoveTTSAudioSourceOnNetworkObject(GameObject objectRefOfSpeaker) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (objectRefOfSpeaker.TryGetComponent(ref val)) { TTSCompanyAPI.RemoveTTSAudioSourceOnNetworkObject(new NetworkObjectReference(val)); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void RemoveTTSAudioSourceOnNetworkObject(NetworkObjectReference networkObjectRefOfSpeaker) { //IL_0012: 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) ulong callingAssemblyHash = HashHelper.GetCallingAssemblyHash(Assembly.GetCallingAssembly()); NetworkObject val = default(NetworkObject); if (LNetworkUtils.IsConnected) { TTSCompanyNetworking.Request_Server_DespawnTTSSource(new DespawnTTSAudioSource_NET(networkObjectRefOfSpeaker, callingAssemblyHash)); } else if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", networkObjectRefOfSpeaker); } else { TTSAudioSourceManager.RemovePermanentTTSAudioSource(((Component)val).gameObject, callingAssemblyHash); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void UpdateTTSAudioSourceSettingsOnNetworkObject(GameObject objectRefOfSpeaker, TTSAudioSourceSettings audioSourceSettings, bool useGlobalAudioSource = true) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (objectRefOfSpeaker.TryGetComponent(ref val)) { TTSCompanyAPI.UpdateTTSAudioSourceSettingsOnNetworkObject(new NetworkObjectReference(val), audioSourceSettings, useGlobalAudioSource); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void UpdateTTSAudioSourceSettingsOnNetworkObject(NetworkObjectReference networkObjectRefOfSpeaker, TTSAudioSourceSettings audioSourceSettings, bool useGlobalAudioSource = true) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) audioSourceSettings = audioSourceSettings ?? DefaultTTSAudioSourceSettings; ulong callingAssemblyHash = (useGlobalAudioSource ? HashHelper.GlobalCallerHash : HashHelper.GetCallingAssemblyHash(Assembly.GetCallingAssembly())); NetworkObject val = default(NetworkObject); if (LNetworkUtils.IsConnected) { TTSCompanyNetworking.Request_Server_UpdateTTSAudioSourceSettings(new UpdateTTSAudioSourceSettings_NET(networkObjectRefOfSpeaker, callingAssemblyHash, audioSourceSettings)); } else if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", networkObjectRefOfSpeaker); } else { TTSAudioSourceManager.UpdateTTSAudioSourceSettings(((Component)val).gameObject, callingAssemblyHash, audioSourceSettings); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void SpeakTTSAtNetworkObject(NetworkObjectReference networkObjectRefOfSpeaker, string[] textsToSpeak, bool useGlobalAudioSource = true, PiperVoiceSettings voiceSettings = null) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) LogConstants.CODE_TRIGGERED.Log("TTSCompanyAPI", "SpeakTTSAtNetworkObject"); if (textsToSpeak != null && textsToSpeak.Length != 0) { voiceSettings = voiceSettings ?? DefaultVoiceSettings; ulong callingAssemblyHash; ulong trackingKeyHash; if (useGlobalAudioSource) { callingAssemblyHash = HashHelper.GlobalCallerHash; trackingKeyHash = HashHelper.GetTrackingKeyHash(((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId); } else { Assembly callingAssembly = Assembly.GetCallingAssembly(); callingAssemblyHash = HashHelper.GetCallingAssemblyHash(callingAssembly); trackingKeyHash = HashHelper.GetTrackingKeyHash(((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId, callingAssembly); } TTSCompanyNetworking.Request_Server_SpeakTTS(new TTSSpeakTTS_NET(networkObjectRefOfSpeaker, callingAssemblyHash, textsToSpeak, voiceSettings, trackingKeyHash)); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void SpeakTTSAtNetworkObject(NetworkObjectReference networkObjectRefOfSpeaker, string textToSpeak, bool useGlobalAudioSource = true, PiperVoiceSettings voiceSettings = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) SpeakTTSAtNetworkObject(networkObjectRefOfSpeaker, TTSCompanyUtils.SplitTextToSpeak(textToSpeak), useGlobalAudioSource, voiceSettings); } [MethodImpl(MethodImplOptions.NoInlining)] public static void SpeakTTSAtNetworkObject(GameObject objectRefOfSpeaker, string textToSpeak, bool useGlobalAudioSource = true, PiperVoiceSettings voiceSettings = null) { SpeakTTSAtNetworkObject(objectRefOfSpeaker, TTSCompanyUtils.SplitTextToSpeak(textToSpeak), useGlobalAudioSource, voiceSettings); } [MethodImpl(MethodImplOptions.NoInlining)] public static void SpeakTTSAtNetworkObject(GameObject objectRefOfSpeaker, string[] textsToSpeak, bool useGlobalAudioSource = true, PiperVoiceSettings voiceSettings = null) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (objectRefOfSpeaker.TryGetComponent(ref val)) { TTSCompanyAPI.SpeakTTSAtNetworkObject(new NetworkObjectReference(val), textsToSpeak, useGlobalAudioSource, voiceSettings); } } public static void PreGenerateTTS(string textToSpeak, PiperVoiceSettings voiceSettings = null) { if (!string.IsNullOrWhiteSpace(textToSpeak)) { PreGenerateTTS(TTSCompanyUtils.SplitTextToSpeak(textToSpeak), voiceSettings); } } public static void PreGenerateTTS(string[] textsToSpeak, PiperVoiceSettings voiceSettings = null) { LogConstants.CODE_TRIGGERED.Log("TTSCompanyAPI", "PreGenerateTTS"); if (textsToSpeak != null && textsToSpeak.Length != 0) { voiceSettings = voiceSettings ?? DefaultVoiceSettings; ulong trackingKeyHash = HashHelper.GetTrackingKeyHash(string.Join("|", textsToSpeak), voiceSettings); CancellationTokenSource cts = new CancellationTokenSource(TTSTimeoutHelper.GetGenerationTimeout(textsToSpeak, voiceSettings)); ((MonoBehaviour)TTSCompanyPlugin.instance).StartCoroutine(TTSCompanyBackend.PreGenerateTTS(trackingKeyHash, textsToSpeak, voiceSettings, cts)); } } } public static class TTSCompanyUtils { private static readonly Regex SentenceRegex = new Regex("[^.!?]+[.!?]?", RegexOptions.Compiled); public static bool HasTTSVoiceModelBeenLoadedIntoMemory(string voiceModelName) { return TTSCompanyPlugin._tts.isVoiceModelLoaded(voiceModelName); } public static string GetRandomFoundTTSVoiceName() { return TTSCompanyPlugin._tts._server._memoryManager.GetRandomFoundTTSVoiceName(); } public static string GetRandomLoadedTTSVoicename() { return TTSCompanyPlugin._tts._server._memoryManager.GetRandomLoadedTTSVoiceName(); } public static bool IsNetworkObjectCurrentlySpeaking(GameObject gameObject) { NetworkObject networkObject = default(NetworkObject); if (gameObject.TryGetComponent(ref networkObject)) { return IsNetworkObjectCurrentlySpeaking(networkObject); } return false; } public static bool IsNetworkObjectCurrentlySpeaking(NetworkObject networkObject) { if ((Object)(object)networkObject == (Object)null) { return false; } GameObject gameObject = ((Component)networkObject).gameObject; foreach (SpeakTTSAudioClipCache value in TTSCompanyBackend.WantedAudioClips.Values) { if ((Object)(object)value._foundNetworkObject == (Object)(object)gameObject) { return true; } } return false; } public static bool IsNetworkObjectAwaitingTTSGeneration(GameObject gameObject) { NetworkObject networkObject = default(NetworkObject); if (gameObject.TryGetComponent(ref networkObject)) { return IsNetworkObjectAwaitingTTSGeneration(networkObject); } return false; } public static bool IsNetworkObjectAwaitingTTSGeneration(NetworkObject networkObject) { if ((Object)(object)networkObject != (Object)null) { return TTSCompanyBackend.GeneratingNetworkObjectIds.ContainsKey(networkObject.NetworkObjectId); } return false; } public static TTSNetworkObjectState GetTTSNetworkObjectState(GameObject gameObject) { NetworkObject networkObject = default(NetworkObject); if (gameObject.TryGetComponent(ref networkObject)) { return GetTTSNetworkObjectState(networkObject); } return TTSNetworkObjectState.Invalid; } public static TTSNetworkObjectState GetTTSNetworkObjectState(NetworkObject networkObject) { if ((Object)(object)networkObject == (Object)null) { return TTSNetworkObjectState.Invalid; } if (IsNetworkObjectCurrentlySpeaking(networkObject)) { return TTSNetworkObjectState.ActivelySpeaking; } if (IsNetworkObjectAwaitingTTSGeneration(networkObject)) { return TTSNetworkObjectState.GeneratingTTS; } return TTSNetworkObjectState.Idle; } internal static string[] SplitTextToSpeak(string textToSpeak) { if (string.IsNullOrEmpty(textToSpeak)) { return Array.Empty(); } MatchCollection matchCollection = SentenceRegex.Matches(textToSpeak); List list = new List(matchCollection.Count); for (int i = 0; i < matchCollection.Count; i++) { Match match = matchCollection[i]; ReadOnlySpan readOnlySpan = MemoryExtensions.AsSpan(textToSpeak, match.Index, match.Length).Trim(); if (readOnlySpan.Length > 0) { list.Add(readOnlySpan.ToString()); } } if (list.Count == 0) { list.Add(textToSpeak); } return list.ToArray(); } internal static float DetermineEndPause(string sentenceText, float sentenceSilence, float punctuationSilence) { if (string.IsNullOrEmpty(sentenceText)) { return 0f; } int num = sentenceText.TrimEnd(Array.Empty()).Length - 1; while (num >= 0 && char.IsWhiteSpace(sentenceText[num])) { num--; } while (num >= 0) { char c = sentenceText[num]; if (c != '"' && c != '\'' && c != ')' && c != ']') { break; } num--; } if (num < 0) { return 0f; } switch (sentenceText[num]) { case '!': case '.': case '?': return sentenceSilence; case ',': case ':': case ';': return punctuationSilence; default: return 0f; } } } } namespace TTSCompany.Patches { [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetworkManagerPatch { [HarmonyPostfix] [HarmonyPatch("ResetGameValuesToDefault")] private static void OnReturnedToMainMenu() { TTSCompanyBackend.OnReturnedToMainMenu(); } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPostfix] [HarmonyPatch("OnPlayerConnectedClientRpc")] private static void SyncTTSAudioSources(ulong clientId) { TTSCompanyNetworking.SyncActiveAudioSourcesTo(clientId); } [HarmonyPostfix] [HarmonyPatch("OnClientDisconnect")] private static void OnPlayerDisconnected(ulong clientId) { TTSCompanyNetworking.HandlePlayerDisconnected(clientId); } } } namespace TTSCompany.Debug { internal static class DebugManualTrigger { private static readonly string[] randomVoiceLines = new string[10] { "This is a testing text-to-speech voice line.", "System online. All networks are fully functional.", "Warning, localized anomaly detected near your position.", "Please do not touch the operational machinery.", "The quick brown fox jumps over the lazy dog.", "I guess...this voice lines works.", "Testing complete.", "This is a voice line test.", "Warning! Retreat immediately!", "FUCK!" }; private static readonly string[] enemyNames = new string[8] { "Barber", "Bracken", "Bunker Spider", "Coil-Head", "Hoarding Bug", "Hygrodere", "Jester", "Nutcracker" }; private static readonly string[] multipleLines = new string[3] { "This is a testing text-to-speech voice line.", "This is a voice line test.", "Testing complete." }; private static PlayerControllerB speakingPlayer = null; private static void GetSpeakingPlayer() { if ((Object)(object)speakingPlayer != (Object)null) { return; } if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.localPlayerController == (Object)null) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("DebugManualTrigger", "GetSpeakingPlayer", 1); } else { speakingPlayer = StartOfRound.Instance.localPlayerController; if (!((Object)(object)speakingPlayer == (Object)null)) { TTSCompanyAPI.AddTTSAudioSourceOnNetworkObject(((Component)speakingPlayer).gameObject); } } } internal static async void TriggerTestTTS01(CallbackContext obj) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (((CallbackContext)(ref obj)).performed) { LogConstants.CODE_TRIGGERED.Log("DebugManualTrigger", "TriggerTestTTS01"); GetSpeakingPlayer(); if ((Object)(object)speakingPlayer == (Object)null) { LogConstants.CODE_TRIGGERED.Log("DebugManualTrigger", "speakingPlayer == null"); return; } PiperVoiceSettings piperVoiceSettings = new PiperVoiceSettings(); piperVoiceSettings.ModelName = TTSCompanyUtils.GetRandomLoadedTTSVoicename(); int num = Random.Range(0, randomVoiceLines.Length); TTSAudioSourceSettings tTSAudioSourceSettings = new TTSAudioSourceSettings(); tTSAudioSourceSettings.Volume = 1f; TTSCompanyAPI.UpdateTTSAudioSourceSettingsOnNetworkObject(((Component)speakingPlayer).gameObject, tTSAudioSourceSettings); TTSCompanyAPI.SpeakTTSAtNetworkObject(((Component)speakingPlayer).gameObject, randomVoiceLines[num], useGlobalAudioSource: true, piperVoiceSettings); } } internal static async void TriggerTestTTS02(CallbackContext obj) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (((CallbackContext)(ref obj)).performed) { LogConstants.CODE_TRIGGERED.Log("DebugManualTrigger", "TriggerTestTTS01"); GetSpeakingPlayer(); if ((Object)(object)speakingPlayer == (Object)null) { LogConstants.CODE_TRIGGERED.Log("DebugManualTrigger", "speakingPlayer == null"); return; } string[] array = new string[3] { "Warning, ", "ENTITYNAME", " detected near your position." }; string[] array2 = new string[3] { "WATCH OUT, ", "ENTITYNAME", " BEHIND YOU!" }; string[][] obj2 = new string[2][] { array, array2 }; PiperVoiceSettings voiceSettings = new PiperVoiceSettings { ModelName = TTSCompanyUtils.GetRandomLoadedTTSVoicename() }; int num = Random.Range(0, array.Length); string[] array3 = obj2[num]; num = Random.Range(0, enemyNames.Length); array3[1] = enemyNames[num]; TTSAudioSourceSettings tTSAudioSourceSettings = new TTSAudioSourceSettings(); tTSAudioSourceSettings.Volume = 0.25f; TTSCompanyAPI.UpdateTTSAudioSourceSettingsOnNetworkObject(((Component)speakingPlayer).gameObject, tTSAudioSourceSettings); TTSCompanyAPI.SpeakTTSAtNetworkObject(((Component)speakingPlayer).gameObject, array3, useGlobalAudioSource: true, voiceSettings); } } } } namespace TTSCompany.Debug.Inputs { public class TTSCompanyDebugInputs : LcInputActions { [InputAction(/*Could not decode attribute arguments.*/)] public InputAction PixelIndieDev_TestTTS_01 { get; set; } [InputAction(/*Could not decode attribute arguments.*/)] public InputAction PixelIndieDev_TestTTS_02 { get; set; } } } namespace TTSCompany.Components { internal sealed class PiperTTSServer { private const string ReadyPrefix = "READY ON PORT "; private Process _process; private int _port; private readonly StringBuilder _stderrLog = new StringBuilder(); internal readonly VoiceModelMemoryManager _memoryManager; internal bool IsRunning { get { if (_process != null) { return !_process.HasExited; } return false; } } internal int Port => _port; public PiperTTSServer() { _memoryManager = new VoiceModelMemoryManager(this); } internal async Task StartAsync(int startupTimeoutMs, CancellationToken cancellationToken) { if (IsRunning) { return true; } if (!File.Exists(TTSConstants.PIPER_EXECUTABLE_LOCATION)) { LogConstants.PIPER_TTS_SERVER_EXE_NOT_FOUND.Log("PiperTTSServer", TTSConstants.PIPER_EXECUTABLE_LOCATION); return false; } if (!Directory.Exists(TTSConstants.TTS_DEFAULT_VOICE_MODELS_FOLDER_LOCATION)) { LogConstants.PIPER_TTS_SERVER_VOICE_FOLDER_NOT_FOUND.Log("PiperTTSServer", TTSConstants.TTS_DEFAULT_VOICE_MODELS_FOLDER_LOCATION); return false; } _memoryManager.InitializeModelRegistry(); ProcessStartInfo startInfo = new ProcessStartInfo { FileName = TTSConstants.PIPER_EXECUTABLE_LOCATION, UseShellExecute = false, RedirectStandardInput = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = false, WorkingDirectory = Path.GetDirectoryName(TTSConstants.PIPER_EXECUTABLE_LOCATION) }; Process process = new Process { StartInfo = startInfo, EnableRaisingEvents = true }; TaskCompletionSource exitTcs = new TaskCompletionSource(); process.Exited += delegate { exitTcs.TrySetResult(result: true); }; try { process.Start(); } catch (Exception ex) { LogConstants.PIPER_TTS_SERVER_VOICE_FOLDER_NOT_FOUND.Log("PiperTTSServer", ex.Message); return false; } DrainStreamAsync(process.StandardError, delegate(string onLine) { lock (_stderrLog) { _stderrLog.AppendLine(onLine); if (_stderrLog.Length > 8000) { _stderrLog.Remove(0, _stderrLog.Length - 8000); } } }); Task readyLineTask = process.StandardOutput.ReadLineAsync(); Task task = Task.Delay(startupTimeoutMs, cancellationToken); Task task2 = await Task.WhenAny(readyLineTask, exitTcs.Task, task).ConfigureAwait(continueOnCapturedContext: false); if (task2 == exitTcs.Task) { string text; lock (_stderrLog) { text = _stderrLog.ToString(); } LogConstants.PIPER_TTS_SERVER_STARTUP_ISSUE.Log("PiperTTSServer", SafeExitCode(process), text); return false; } if (task2 != readyLineTask) { LogConstants.PIPER_TTS_SERVER_STARTUP_ISSUE.Log("PiperTTSServer", "Timed out", "Timed out waiting for server to report its port"); TryKill(process); return false; } string text2 = await readyLineTask.ConfigureAwait(continueOnCapturedContext: false); if (text2 == null || !text2.StartsWith("READY ON PORT ", StringComparison.Ordinal) || !int.TryParse(text2.Substring("READY ON PORT ".Length).Trim(), out _port)) { string text3; lock (_stderrLog) { text3 = _stderrLog.ToString(); } LogConstants.PIPER_TTS_SERVER_STARTUP_ISSUE.Log("PiperTTSServer", "Unexpected startup output at: " + text2, text3); TryKill(process); return false; } DrainStreamAsync(process.StandardOutput, delegate(string outLine) { LogConstants.PIPER_TTS_SERVER_OUTPUT_DRAIN.Log("PiperTTSServer", outLine); }); _process = process; LogConstants.PIPER_TTS_SERVER_SUCCESS_STARTUP.Log("PiperTTSServer", _port, process.Id); return true; } internal async Task ShutdownAsync(int timeoutMs = 3000) { Process process = _process; if (process == null) { return; } if (!process.HasExited) { try { await SendSimpleCommandAsync("{\"command\":\"shutdown\"}\n", CancellationToken.None, 1000).ConfigureAwait(continueOnCapturedContext: false); } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "SendSimpleCommandAsync"); } } try { if (!process.HasExited) { TaskCompletionSource exitTcs = new TaskCompletionSource(); process.EnableRaisingEvents = true; process.Exited += delegate { exitTcs.TrySetResult(result: true); }; if (process.HasExited) { exitTcs.TrySetResult(result: true); } if (await Task.WhenAny(new Task[2] { exitTcs.Task, Task.Delay(timeoutMs) }).ConfigureAwait(continueOnCapturedContext: false) != exitTcs.Task) { TryKill(process); } } } catch { TryKill(process); } finally { _process = null; LogConstants.PIPER_TTS_SERVER_STOPPED.Log("PiperTTSServer"); } } internal bool HasVoiceModelBeenLoaded(string modelName) { return _memoryManager.HasVoiceModelBeenLoaded(modelName); } internal bool IsVoiceModelValid(string modelName) { return _memoryManager.IsVoiceModelValid(modelName); } internal async Task<(bool Success, string Error)> LoadModelAsync(string modelName, ulong callingAssemblyHash, CancellationToken cancellationToken) { return await _memoryManager.LoadModelAsync(modelName, callingAssemblyHash, cancellationToken); } internal async Task<(bool Success, string Error)> UnloadModelAsync(string modelName, ulong callingAssemblyHash, CancellationToken cancellationToken) { return await _memoryManager.UnloadModelAsync(modelName, callingAssemblyHash, cancellationToken); } internal async Task> SendSimpleCommandAsync(string requestJsonLine, CancellationToken cancellationToken, int timeoutMs = 30000) { TcpClient client = new TcpClient(); try { using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken[1] { cancellationToken }); cts.CancelAfter(timeoutMs); using (cts.Token.Register(delegate { try { client.Close(); } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "SendSimpleCommandAsync"); } })) { await ConnectAsync(client, _port, cts.Token).ConfigureAwait(continueOnCapturedContext: false); client.NoDelay = true; NetworkStream stream = client.GetStream(); byte[] bytes = Encoding.UTF8.GetBytes(requestJsonLine); await stream.WriteAsync(bytes, 0, bytes.Length, cts.Token).ConfigureAwait(continueOnCapturedContext: false); return JSONHelper.ParseFlatObject((await ReadLineWithLeftoverAsync(stream, cts.Token).ConfigureAwait(continueOnCapturedContext: false)).Item1); } } finally { if (client != null) { ((IDisposable)client).Dispose(); } } } internal (bool Success, string Error) ToResult(Dictionary response) { int num; object obj; if (response.TryGetValue("status", out var value)) { num = ((value as string == "ok") ? 1 : 0); if (num != 0) { obj = null; goto IL_0044; } } else { num = 0; } obj = (response.TryGetValue("message", out var value2) ? (value2 as string) : "unknown error"); goto IL_0044; IL_0044: string item = (string)obj; return (Success: (byte)num != 0, Error: item); } internal async Task PingAsync(CancellationToken cancellationToken) { try { bool b = default(bool); int num; if ((await SendSimpleCommandAsync("{\"command\":\"ping\"}\n", cancellationToken).ConfigureAwait(continueOnCapturedContext: false)).TryGetValue("alive", out var value)) { if (value is bool) { b = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (b ? 1u : 0u)) != 0; } catch { return false; } } internal async Task SynthesizeAsync(string text, string hash, PiperVoiceSettings options, CancellationToken cancellationToken) { if (!_memoryManager.HasVoiceModelBeenLoaded(options.ModelName)) { LogConstants.PIPER_TTS_VOICE_MODEL_NOT_LOADED.Log("PiperTTSServer", options.ModelName); return TTSRawResult.Cancelled(); } if (_memoryManager.WasVoiceModelEvicted(options.ModelName)) { if (!(await _memoryManager.ReloadModelAsync(options.ModelName, cancellationToken)).Item1) { return TTSRawResult.Cancelled(); } } else { _memoryManager.UpdateLastUse(options.ModelName); } cancellationToken.ThrowIfCancellationRequested(); int port = _port; TcpClient client = null; try { client = new TcpClient(); using (cancellationToken.Register(delegate { try { client.Close(); } catch (Exception ex5) { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "SynthesizeAsync", ex5); } SendCancelAsync(hash, port); })) { await ConnectAsync(client, port, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); client.NoDelay = true; NetworkStream stream = client.GetStream(); string s = BuildSynthesizeRequest(options.ModelName, text, hash, options); byte[] bytes = Encoding.UTF8.GetBytes(s); await stream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); (string, byte[]) obj = await ReadLineWithLeftoverAsync(stream, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); string item = obj.Item1; byte[] item2 = obj.Item2; Dictionary dictionary = JSONHelper.ParseFlatObject(item); object value; string text2 = (dictionary.TryGetValue("status", out value) ? (value as string) : null); switch (text2) { case "ok": { object value3; int sampleRate = ((dictionary.TryGetValue("sample_rate", out value3) && value3 != null) ? Convert.ToInt32(value3, CultureInfo.InvariantCulture) : 22050); using MemoryStream ms = new MemoryStream(); if (item2.Length != 0) { ms.Write(item2, 0, item2.Length); } await stream.CopyToAsync(ms, 81920, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return TTSRawResult.Ok(ms.ToArray(), sampleRate); } case "cancelled": return TTSRawResult.Cancelled(); case "error": { object value2; return TTSRawResult.Failure(dictionary.TryGetValue("message", out value2) ? (value2 as string) : "unknown error"); } default: return TTSRawResult.Failure("unexpected response status: '" + text2 + "'"); } } } catch (OperationCanceledException) { return TTSRawResult.Cancelled(); } catch (ObjectDisposedException) { return cancellationToken.IsCancellationRequested ? TTSRawResult.Cancelled() : TTSRawResult.Failure("connection closed unexpectedly"); } catch (IOException ex3) { return cancellationToken.IsCancellationRequested ? TTSRawResult.Cancelled() : TTSRawResult.Failure(ex3.Message); } catch (SocketException ex4) { return TTSRawResult.Failure("socket error: " + ex4.Message); } finally { client?.Close(); } } private static string BuildSynthesizeRequest(string modelPath, string text, string hash, PiperVoiceSettings options) { StringBuilder stringBuilder = new StringBuilder(text.Length + 128); stringBuilder.Append("{\"command\":\"synthesize\""); stringBuilder.Append(",\"model\":\"").Append(JSONHelper.Escape(modelPath)).Append('"'); stringBuilder.Append(",\"text\":\"").Append(JSONHelper.Escape(text)).Append('"'); stringBuilder.Append(",\"hash\":\"").Append(JSONHelper.Escape(hash)).Append('"'); stringBuilder.Append(",\"length_scale\":").Append((1f / options.SpeechRate).ToString("F4", CultureInfo.InvariantCulture)); stringBuilder.Append(",\"noise_scale\":").Append(options.NoiseScale.ToString("F4", CultureInfo.InvariantCulture)); stringBuilder.Append(",\"noise_w\":").Append(options.NoiseScaleW.ToString("F4", CultureInfo.InvariantCulture)); stringBuilder.Append("}\n"); return stringBuilder.ToString(); } private async Task SendCancelAsync(string hash, int port) { if (string.IsNullOrEmpty(hash)) { return; } try { using TcpClient client = new TcpClient(); Task connectTask = client.ConnectAsync(IPAddress.Loopback, port); if (await Task.WhenAny(new Task[2] { connectTask, Task.Delay(1000) }).ConfigureAwait(continueOnCapturedContext: false) != connectTask) { return; } await connectTask.ConfigureAwait(continueOnCapturedContext: false); client.NoDelay = true; string s = "{\"command\":\"cancel\",\"hash\":\"" + JSONHelper.Escape(hash) + "\"}\n"; byte[] bytes = Encoding.UTF8.GetBytes(s); await client.GetStream().WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(continueOnCapturedContext: false); } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "SendCancelAsync"); } } private static async Task ConnectAsync(TcpClient client, int port, CancellationToken cancellationToken) { using (cancellationToken.Register(delegate { try { client.Close(); } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "ConnectAsync"); } })) { await client.ConnectAsync(IPAddress.Loopback, port).ConfigureAwait(continueOnCapturedContext: false); } } private static async Task<(string Line, byte[] Leftover)> ReadLineWithLeftoverAsync(NetworkStream stream, CancellationToken cancellationToken) { byte[] buffer = new byte[4096]; using MemoryStream ms = new MemoryStream(); while (true) { int num = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (num == 0) { break; } int num2 = Array.IndexOf(buffer, (byte)10, 0, num); if (num2 >= 0) { ms.Write(buffer, 0, num2); int num3 = num - num2 - 1; byte[] array = Array.Empty(); if (num3 > 0) { array = new byte[num3]; Array.Copy(buffer, num2 + 1, array, 0, num3); } return (Line: Encoding.UTF8.GetString(ms.ToArray()), Leftover: array); } ms.Write(buffer, 0, num); } return (Line: Encoding.UTF8.GetString(ms.ToArray()), Leftover: Array.Empty()); } private static async Task DrainStreamAsync(StreamReader reader, Action onLine) { try { while (true) { string text = await reader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); if (text != null) { onLine?.Invoke(text); continue; } break; } } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "DrainStreamAsync"); } } private static void TryKill(Process process) { try { if (!process.HasExited) { process.Kill(); } } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "TryKill"); } } private static int SafeExitCode(Process process) { try { return process.HasExited ? process.ExitCode : (-1); } catch { LogConstants.CODE_GENERIC_CATCH.Log("PiperTTSServer", "SafeExitCode"); return -1; } } } internal static class TTSCompanyBackend { private static readonly ConcurrentDictionary ActiveTTSCoroutines = new ConcurrentDictionary(); private static readonly ConcurrentDictionary ActivePreGenTasks = new ConcurrentDictionary(); internal static readonly ConcurrentDictionary WantedAudioClips = new ConcurrentDictionary(); internal static readonly ConcurrentDictionary SpeakingNetworkObjectIds = new ConcurrentDictionary(); internal static readonly ConcurrentDictionary GeneratingNetworkObjectIds = new ConcurrentDictionary(); internal static void SpeakTTSAtNetworkObject_OnClient(TTSSpeakTTS_PLUS_NET data) { //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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) LogConstants.CODE_TRIGGERED.Log("TTSCompanyBackend", "SpeakTTSAtNetworkObject_OnClient"); if (ActiveTTSCoroutines.TryGetValue(data._trackingKeyHash, out var value)) { if (value.Cts != null) { value.Cts.SafeCancel(); } if (value.Coroutine != null) { ((MonoBehaviour)TTSCompanyPlugin.instance).StopCoroutine(value.Coroutine); } GeneratingNetworkObjectIds.TryRemove(value.NetworkObjectId, out var _); ActiveTTSCoroutines.TryRemove(data._trackingKeyHash, out var _); } CancellationTokenSource cts = new CancellationTokenSource(); ActiveTTSState obj = new ActiveTTSState { Cts = cts }; NetworkObjectReference networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; obj.NetworkObjectId = ((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId; ActiveTTSState activeTTSState = obj; if (!((Object)(object)TTSCompanyPlugin.instance == (Object)null)) { activeTTSState.Coroutine = ((MonoBehaviour)TTSCompanyPlugin.instance).StartCoroutine(SpeakMultipleTTSInternalRoutine(data._sessionId, data._trackingKeyHash, data._networkObjectRefOfSpeaker, data._callingAssemblyHash, data._textsToSpeak, data._voiceSettings, cts)); ActiveTTSCoroutines[data._trackingKeyHash] = activeTTSState; ConcurrentDictionary generatingNetworkObjectIds = GeneratingNetworkObjectIds; networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; generatingNetworkObjectIds.TryAdd(((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId, value: false); } } internal static IEnumerator SpeakMultipleTTSInternalRoutine(ulong sessionId, ulong trackingKeyHash, NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash, string[] textsToSpeak, PiperVoiceSettings voiceSettings, CancellationTokenSource cts) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) LogConstants.CODE_TRIGGERED.Log("TTSCompanyBackend", "SpeakMultipleTTSInternalRoutine"); try { Task[] ttsTasks = new Task[textsToSpeak.Length]; for (int i = 0; i < textsToSpeak.Length; i++) { ttsTasks[i] = TTSCompanyPlugin._tts.GenerateTTSAsync(textsToSpeak[i], voiceSettings, cts.Token); } TTSCompanyNetworking.CreateClientTask(sessionId, networkObjectRefOfSpeaker, callingAssemblyHash, textsToSpeak, voiceSettings.SentenceSilence, voiceSettings.PunctuationSilence, cts); for (int j = 0; j < ttsTasks.Length; j++) { Task currentTask = ttsTasks[j]; yield return (object)new WaitUntil((Func)(() => currentTask.IsCompleted)); if (currentTask.IsFaulted || currentTask.IsCanceled || !currentTask.Result.Success || (Object)(object)currentTask.Result.AudioClip == (Object)null) { cts.SafeCancel(); break; } TTSResult result = currentTask.Result; TTSCompanyNetworking.UpdateClientTask(sessionId, j, result.AudioClip); TTSCompanyNetworking.Request_Server_UpdateSentenceProgress(new SentenceProgressData_NET(sessionId, j, success: true)); } } finally { cts.Dispose(); if (ActiveTTSCoroutines.TryGetValue(trackingKeyHash, out var value) && value.Cts == cts) { ActiveTTSCoroutines.TryRemove(trackingKeyHash, out var _); GeneratingNetworkObjectIds.TryRemove(((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId, out var _); } } } internal static void PlaySpeakTTSAtNetworkObject_OnClient(ulong taskid, NetworkObjectReference networkObjectReference, ulong callingAssemblyHash, AudioClip[] audioClip, float[] pauseDurations, bool isFinalBatch) { NetworkObject val = default(NetworkObject); if (audioClip == null || !((NetworkObjectReference)(ref networkObjectReference)).TryGet(ref val, (NetworkManager)null)) { return; } GameObject gameObject = ((Component)val).gameObject; if (!((Object)(object)gameObject == (Object)null) && gameObject.activeInHierarchy) { if (WantedAudioClips.TryGetValue(taskid, out var value)) { value.AddAudioClips(audioClip, pauseDurations); } else { value = new SpeakTTSAudioClipCache(gameObject, callingAssemblyHash, audioClip, pauseDurations); WantedAudioClips.TryAdd(taskid, value); SpeakingNetworkObjectIds.TryAdd(val.NetworkObjectId, value: false); } if (isFinalBatch) { value.MarkLastBatch(); } } } internal static IEnumerator PreGenerateTTS(ulong trackingKeyHash, string[] textsToSpeak, PiperVoiceSettings voiceSettings, CancellationTokenSource cts) { LogConstants.CODE_TRIGGERED.Log("TTSCompanyBackend", "PreGenerateTTS"); if (ActivePreGenTasks.TryRemove(trackingKeyHash, out var value)) { value.SafeCancel(); } ActivePreGenTasks[trackingKeyHash] = cts; try { Task[] ttsTasks = new Task[textsToSpeak.Length]; for (int i = 0; i < textsToSpeak.Length; i++) { ttsTasks[i] = TTSCompanyPlugin._tts.GenerateTTSAsync(textsToSpeak[i], voiceSettings, cts.Token); } foreach (Task currentTask in ttsTasks) { yield return (object)new WaitUntil((Func)(() => currentTask.IsCompleted)); if (currentTask.IsFaulted || currentTask.IsCanceled || !currentTask.Result.Success) { cts.SafeCancel(); break; } TTSResult result = currentTask.Result; if ((Object)(object)result.AudioClip != (Object)null) { Object.Destroy((Object)(object)result.AudioClip); } } } finally { cts.Dispose(); if (ActivePreGenTasks.TryGetValue(trackingKeyHash, out var value2) && value2 == cts) { ActivePreGenTasks.TryRemove(trackingKeyHash, out var _); } } } internal static void OnReturnedToMainMenu() { foreach (ActiveTTSState value in ActiveTTSCoroutines.Values) { value.Cts?.SafeCancel(); } ActiveTTSCoroutines.Clear(); foreach (SpeakTTSAudioClipCache value2 in WantedAudioClips.Values) { QueuedClip result; while (value2._audioQueue.TryDequeue(out result)) { if ((Object)(object)result.Clip != (Object)null) { Object.Destroy((Object)(object)result.Clip); } } } WantedAudioClips.Clear(); SpeakingNetworkObjectIds.Clear(); GeneratingNetworkObjectIds.Clear(); TTSCompanyNetworking.ClearClientTasks(); TTSCompanyNetworking.ClearServerTasks(); } } internal sealed class TTSGenerator { internal readonly PiperTTSServer _server = new PiperTTSServer(); private readonly ConcurrentDictionary _inFlightRequests = new ConcurrentDictionary(); private int _maxConcurrent; private SemaphoreSlim _semaphore; private bool _disposed; private bool _isAvailable; private static readonly int CPU_totalCores = Environment.ProcessorCount; private static readonly int CPU_coresReservedForGame = Mathf.Max(1, Mathf.CeilToInt((float)CPU_totalCores * 0.1f)); private const int CPU_minimumMaxConcurrentRequests = 1; private static readonly int CPU_availableCoresForTTS = Math.Max(1, CPU_totalCores - CPU_coresReservedForGame); internal int MaxConcurrentRequests { get { return _maxConcurrent; } set { if (value < 1) { LogConstants.TTS_GENERATOR_ARGUMENT_OUT_OF_RANGE_EX.Log("TTSGenerator"); } int num = (_maxConcurrent = Math.Max(1, value)); _ = _semaphore; _semaphore = new SemaphoreSlim(num, num); } } internal TTSGenerator() { SetMaxConcurrentRequests(TTSGenPriority.Normal); } private void SetMaxConcurrentRequests(int maxConcurrentRequests) { MaxConcurrentRequests = maxConcurrentRequests; LogConstants.CODE_NEW_VALUE_SET.Log("TTSGenerator", "maxConcurrentRequests", MaxConcurrentRequests); } internal void SetMaxConcurrentRequests(TTSGenPriority priority) { switch (priority) { case TTSGenPriority.VeryLow: SetMaxConcurrentRequests(Math.Max(1, CPU_availableCoresForTTS / 6)); break; case TTSGenPriority.Low: SetMaxConcurrentRequests(Math.Max(1, CPU_availableCoresForTTS / 4)); break; default: SetMaxConcurrentRequests(Math.Max(1, CPU_availableCoresForTTS / 2)); break; case TTSGenPriority.High: SetMaxConcurrentRequests(Math.Max(1, (int)((float)CPU_availableCoresForTTS * 0.75f))); break; case TTSGenPriority.Max: SetMaxConcurrentRequests(CPU_availableCoresForTTS); break; } } internal async Task InitializeAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (_isAvailable) { return true; } if (!FolderHelper.CheckForPiperTTS()) { LogConstants.TTS_GENERATOR_UNZIP_FAILED.Log("TTSGenerator", "piper-server.exe"); return false; } if (!FolderHelper.CheckForDefaultVoiceModels()) { LogConstants.TTS_GENERATOR_UNZIP_FAILED.Log("TTSGenerator", "TTS-Company-Voices"); return false; } bool flag = await _server.StartAsync(15000, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); _isAvailable = flag; return flag; } internal async Task ShutdownAsync() { if (!_disposed) { _disposed = true; _isAvailable = false; await _server.ShutdownAsync().ConfigureAwait(continueOnCapturedContext: false); _semaphore?.Dispose(); } } internal void Dispose() { if (!_disposed) { _disposed = true; try { ShutdownAsync().GetAwaiter().GetResult(); } catch { LogConstants.CODE_GENERIC_CATCH.Log("TTSGenerator", "Dispose"); } _semaphore?.Dispose(); } } internal Task<(bool Success, string Error)> PreloadVoiceAsync(string voiceName, ulong callingAssemblyHash, CancellationToken cancellationToken = default(CancellationToken)) { if (!_isAvailable || _disposed) { return Task.FromResult((false, "TTS server is not available")); } if (string.IsNullOrWhiteSpace(voiceName)) { return Task.FromResult((false, "voice model name must not be empty")); } return _server.LoadModelAsync(voiceName, callingAssemblyHash, cancellationToken); } internal Task<(bool Success, string Error)> UnloadVoiceAsync(string voiceName, ulong callingAssemblyHash, CancellationToken cancellationToken = default(CancellationToken)) { if (!_isAvailable || _disposed) { return Task.FromResult((false, "TTS server is not available")); } if (string.IsNullOrWhiteSpace(voiceName)) { return Task.FromResult((false, "voice model name must not be empty")); } return _server.UnloadModelAsync(voiceName, callingAssemblyHash, cancellationToken); } internal bool isVoiceModelLoaded(string voiceModelName) { return _server.HasVoiceModelBeenLoaded(voiceModelName); } internal async Task GenerateTTSAsync(string textToSpeak, PiperVoiceSettings settings, CancellationToken cancellationToken) { if (!_isAvailable || _disposed) { return new TTSResult { AudioClip = null, Success = false }; } cancellationToken.ThrowIfCancellationRequested(); string hashCacheFileName = await Task.Run(delegate { if (!ValidateInputs(textToSpeak, settings)) { return string.Empty; } Directory.CreateDirectory(TTSConstants.TTS_VOICE_CACHE_SOUNDCLIPS_PATH); return HashHelper.GetHashTTSFileNameWithFileType(textToSpeak, settings); }, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (string.IsNullOrWhiteSpace(hashCacheFileName)) { return new TTSResult { AudioClip = null, Success = false }; } string fullCachePath = Path.Combine(TTSConstants.TTS_VOICE_CACHE_SOUNDCLIPS_PATH, hashCacheFileName); if (File.Exists(fullCachePath) && new FileInfo(fullCachePath).Length > 0) { LogConstants.TTS_GENERATOR_FOUND_CACHED_TTS.Log("TTSGenerator", hashCacheFileName); AudioClip val = await LoadAudioClipFromDiskAsync(fullCachePath, hashCacheFileName).ConfigureAwait(continueOnCapturedContext: false); if ((Object)(object)val != (Object)null) { return new TTSResult { AudioClip = val, Success = true }; } } _inFlightRequests.GetOrAdd(hashCacheFileName, (string _) => new BusyGeneration((CancellationToken ct) => RunGenerationAsync(hashCacheFileName, fullCachePath, textToSpeak, settings, ct))); BusyGeneration inFlight; BusyGeneration value; while (true) { inFlight = _inFlightRequests.GetOrAdd(hashCacheFileName, (string _) => new BusyGeneration((CancellationToken ct) => RunGenerationAsync(hashCacheFileName, fullCachePath, textToSpeak, settings, ct))); if (inFlight.TryAddBusy()) { break; } _inFlightRequests.TryRemove(hashCacheFileName, out value); } try { TaskCompletionSource cancellationTcs = new TaskCompletionSource(); using (cancellationToken.Register(delegate { cancellationTcs.TrySetCanceled(cancellationToken); })) { if (await Task.WhenAny(new Task[2] { inFlight.Task, cancellationTcs.Task }).ConfigureAwait(continueOnCapturedContext: false) == cancellationTcs.Task) { LogConstants.TTS_GENERATOR_TTS_CANCELLED.Log("TTSGenerator", textToSpeak, hashCacheFileName); await cancellationTcs.Task.ConfigureAwait(continueOnCapturedContext: false); } return await inFlight.Task.ConfigureAwait(continueOnCapturedContext: false); } } finally { inFlight.RemoveBusy(); if (inFlight.Task.IsCompleted) { _inFlightRequests.TryRemove(hashCacheFileName, out value); } } } private async Task RunGenerationAsync(string hashCacheFileName, string fullCachePath, string textToSpeak, PiperVoiceSettings settings, CancellationToken sharedCancellationToken) { SemaphoreSlim semaphore = _semaphore; await semaphore.WaitAsync(sharedCancellationToken).ConfigureAwait(continueOnCapturedContext: false); try { if (File.Exists(fullCachePath) && new FileInfo(fullCachePath).Length > 0) { AudioClip val = await LoadAudioClipFromDiskAsync(fullCachePath, hashCacheFileName); return new TTSResult { AudioClip = val, Success = ((Object)(object)val != (Object)null) }; } TTSResult endResult = new TTSResult(); if (!(await _server.PingAsync(sharedCancellationToken))) { return endResult; } LogConstants.TTS_GENERATOR_GENERATING_TTS.Log("TTSGenerator", textToSpeak, hashCacheFileName); TTSRawResult tTSRawResult = await _server.SynthesizeAsync(textToSpeak, hashCacheFileName, settings, sharedCancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (!tTSRawResult.IsSuccess) { endResult.AudioClip = null; endResult.Success = false; LogConstants.CODE_GENERIC_FAIL.Log("TTSGenerator", "synthResult", tTSRawResult.Error); return endResult; } if (await ConvertPcmToOggAsync(tTSRawResult.Pcm, tTSRawResult.SampleRate, hashCacheFileName, fullCachePath, sharedCancellationToken)) { TTSResult tTSResult = endResult; tTSResult.AudioClip = await LoadAudioClipFromDiskAsync(fullCachePath, hashCacheFileName); endResult.Success = (Object)(object)endResult.AudioClip != (Object)null; } return endResult; } finally { if (File.Exists(fullCachePath) && new FileInfo(fullCachePath).Length == 0L) { TryDeleteCorruptedCache(fullCachePath, hashCacheFileName); } try { semaphore.Release(); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "RunGenerationAsync", ex); } _inFlightRequests.TryRemove(hashCacheFileName, out var _); } } private static Task ConvertPcmToOggAsync(byte[] pcmData, int sourceSampleRate, string fileHashName, string oggOutputPath, CancellationToken cancellationToken) { LogConstants.CODE_TRIGGERED.Log("TTSGenerator", "ConvertPcmToOggAsync"); return Task.Run(delegate { string text = oggOutputPath + "." + Guid.NewGuid().ToString("N") + ".tmp"; try { short[] array = new short[pcmData.Length / 2]; Buffer.BlockCopy(pcmData, 0, array, 0, pcmData.Length); short[] array2 = ((sourceSampleRate == 24000) ? array : Resample(array, sourceSampleRate, 24000)); cancellationToken.ThrowIfCancellationRequested(); using (FileStream outputStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None)) { IOpusEncoder opusEncoder = OpusCodecFactory.CreateEncoder(24000, 1, OpusApplication.OPUS_APPLICATION_VOIP); opusEncoder.Bitrate = 16000; opusEncoder.UseVBR = true; OpusOggWriteStream opusOggWriteStream = new OpusOggWriteStream(opusEncoder, outputStream); opusOggWriteStream.WriteSamples(array2, 0, array2.Length); opusOggWriteStream.Finish(); } if (File.Exists(oggOutputPath) && new FileInfo(oggOutputPath).Length > 0) { TryDeleteTempFile(text); return true; } AtomicReplace(text, oggOutputPath); return true; } catch (Exception ex) { TryDeleteTempFile(text); LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ConvertPcmToOggAsync", ex); return false; } }); } private static void AtomicReplace(string tempPath, string destPath) { try { if (File.Exists(destPath)) { File.Delete(destPath); } File.Move(tempPath, destPath); } catch (IOException) { TryDeleteTempFile(tempPath); } } private static void TryDeleteTempFile(string path) { try { if (File.Exists(path)) { File.Delete(path); } } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "TryDeleteTempFile", ex); } } private static short[] Resample(short[] input, int sourceRate, int targetRate) { if (sourceRate == targetRate || input.Length == 0) { return input; } double num = (double)sourceRate / (double)targetRate; int num2 = (int)((double)input.Length * ((double)targetRate / (double)sourceRate)); short[] array = new short[num2]; for (int i = 0; i < num2; i++) { double num3 = (double)i * num; int num4 = (int)Math.Floor(num3); int num5 = Math.Min(num4 + 1, input.Length - 1); double num6 = num3 - (double)num4; array[i] = (short)((1.0 - num6) * (double)input[num4] + num6 * (double)input[num5]); } return array; } private static void TryDeleteCorruptedCache(string fullCachePath, string hashCacheFileName) { try { if (File.Exists(fullCachePath) && new FileInfo(fullCachePath).Length == 0L) { LogConstants.TTS_GENERATOR_DELETE_0KB_CACHE.Log("TTSGenerator", hashCacheFileName); File.Delete(fullCachePath); } } catch (Exception ex) { LogConstants.TTS_GENERATOR_FAILED_TO_DELETE_0KB_CACHE.Log("TTSGenerator", hashCacheFileName, ex.Message); } } private static Task LoadAudioClipFromDiskAsync(string absoluteFilePath, string clipName) { if (!File.Exists(absoluteFilePath)) { LogConstants.TTS_GENERATOR_NO_CACHED_AUDIO_FOUND.Log("TTSGenerator", clipName, absoluteFilePath); return Task.FromResult(null); } TaskCompletionSource taskCompletionSource = new TaskCompletionSource(); ((MonoBehaviour)TTSCompanyPlugin.instance).StartCoroutine(LoadCoroutine(absoluteFilePath, clipName, taskCompletionSource)); return taskCompletionSource.Task; } private static IEnumerator LoadCoroutine(string absoluteFilePath, string clipName, TaskCompletionSource tcs) { Task decodeTask = Task.Run(() => DecodeOggOffThread(absoluteFilePath)); yield return (object)new WaitUntil((Func)(() => decodeTask.IsCompleted)); if (decodeTask.IsFaulted) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "LoadCoroutine", decodeTask.Exception?.GetBaseException().Message); tcs.SetResult(null); } else if (decodeTask.Result == null || decodeTask.Result.Length == 0) { tcs.SetResult(null); } else { AudioClip val = AudioClip.Create(clipName, decodeTask.Result.Length, 1, 24000, false); val.SetData(decodeTask.Result, 0); tcs.SetResult(val); } } private static float[] DecodeOggOffThread(string absoluteFilePath) { for (int i = 1; i <= 3; i++) { try { using FileStream stream = new FileStream(absoluteFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); OpusOggReadStream opusOggReadStream = new OpusOggReadStream(OpusCodecFactory.CreateDecoder(24000, 1), stream); List list = new List(); while (opusOggReadStream.HasNextPacket) { short[] array = opusOggReadStream.DecodeNextPacket(); if (array != null) { for (int j = 0; j < array.Length; j++) { list.Add((float)array[j] / 32768f); } } } return list.ToArray(); } catch (IOException) when (i < 3) { Thread.Sleep(50 * i); } catch (Exception ex2) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "DecodeOggOffThread", ex2.Message); return null; } } return null; } private bool ValidateInputs(string textToSpeak, PiperVoiceSettings settings) { if (string.IsNullOrWhiteSpace(textToSpeak)) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ValidateInputs - textToSpeak", "TTS text cannot be empty"); return false; } if (settings == null) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ValidateInputs - settings", "PiperVoiceSettings cannot be NULL"); return false; } if (string.IsNullOrWhiteSpace(settings.ModelName)) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ValidateInputs - settings.ModelName", "Voice model name must be set in settings"); return false; } if (!_server.IsVoiceModelValid(settings.ModelName)) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ValidateInputs - IsVoiceModelValid(settings.ModelName)", "Piper voice model not found or valid"); return false; } if (settings.SpeechRate <= 0f) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSGenerator", "ValidateInputs - settings.SpeechRate", "Speech rate must be > 0"); return false; } return true; } } public sealed class PiperVoiceSettings { private string modelNameWithoutPathOrExtention = "en_US-hfc_female-medium"; private float speechRate = 1f; private float noiseScale = 0.67f; private float noiseScaleW = 0.8f; private float sentenceSilence = 0.2f; private float punctuationSilence = 0.08f; [SerializeField] public string ModelName { get { return modelNameWithoutPathOrExtention; } set { string text = VoiceHelper.CleanupVoiceModelname(value); if (modelNameWithoutPathOrExtention != text) { modelNameWithoutPathOrExtention = text; } } } [SerializeField] public float SpeechRate { get { return speechRate; } set { speechRate = ClampHelper.ClampAndRound(value, 0.05f, 5f); } } [SerializeField] public float NoiseScale { get { return noiseScale; } set { noiseScale = ClampHelper.ClampAndRound(value, 0f, 1f); } } [SerializeField] public float NoiseScaleW { get { return noiseScaleW; } set { noiseScaleW = ClampHelper.ClampAndRound(value, 0f, 1f); } } [SerializeField] public float SentenceSilence { get { return sentenceSilence; } set { sentenceSilence = ClampHelper.ClampAndRound(value, 0f, 5f); } } [SerializeField] public float PunctuationSilence { get { return punctuationSilence; } set { punctuationSilence = ClampHelper.ClampAndRound(value, 0f, 2.5f); } } } public sealed class TTSAudioSourceSettings { private int priority = 128; private float volume = 1f; private float spatialBlend = 1f; private float reverbZoneMix = 1f; private float dopplerLevel; private float minDistance = 1f; private float maxDistance = 40f; [SerializeField] public bool BypassEffects { get; set; } [SerializeField] public bool BypassListenerEffects { get; set; } [SerializeField] public bool BypassReverbZones { get; set; } [SerializeField] public int Priority { get { return priority; } set { priority = Mathf.Clamp(value, 0, 256); } } [SerializeField] public float Volume { get { return volume; } set { volume = Mathf.Clamp(value, 0f, 1f); } } [SerializeField] public float SpatialBlend { get { return spatialBlend; } set { spatialBlend = Mathf.Clamp(value, 0f, 1f); } } [SerializeField] public float ReverbZoneMix { get { return reverbZoneMix; } set { reverbZoneMix = Mathf.Clamp(value, 0f, 1f); } } [SerializeField] public float DopplerLevel { get { return dopplerLevel; } set { dopplerLevel = Mathf.Clamp(value, 0f, 1f); } } [SerializeField] public float _minDistance { get; set; } = 1f; public float MinDistance { get { return minDistance; } set { minDistance = Mathf.Clamp(value, 0f, 128f); } } [SerializeField] public float MaxDistance { get { return maxDistance; } set { maxDistance = Mathf.Clamp(value, 1f, 128f); } } [SerializeField] public AudioRolloffMode RolloffMode { get; set; } = (AudioRolloffMode)1; [SerializeField] public AudioMixerGroup OutputAudioMixerGroup { get; set; } [SerializeField] public (AudioSourceCurveType type, AnimationCurve curve)? CustomCurve { get; set; } } public sealed class TTSResult { public AudioClip AudioClip { get; set; } public bool Success { get; set; } } internal sealed class TTSPlaybackManager : MonoBehaviour { private readonly Dictionary _activeCoroutines = new Dictionary(); private void Update() { foreach (ulong key in TTSCompanyBackend.WantedAudioClips.Keys) { if (!_activeCoroutines.ContainsKey(key)) { Coroutine value = ((MonoBehaviour)this).StartCoroutine(ProcessAudioQueue(key)); _activeCoroutines.Add(key, value); } } } private IEnumerator ProcessAudioQueue(ulong speakerHash) { SpeakTTSAudioClipCache cache; while (TTSCompanyBackend.WantedAudioClips.TryGetValue(speakerHash, out cache) && !((Object)(object)cache._foundNetworkObject == (Object)null)) { if (cache._audioQueue.TryDequeue(out var queued)) { if (TTSAudioSourceManager.PlayAudioSource(cache._foundNetworkObject, cache._callingAssemblyHash, queued.Clip)) { yield return (object)new WaitForSeconds(queued.Clip.length); if ((!cache._isLastBatch || !cache._audioQueue.IsEmpty) && queued.PauseAfter > 0f) { yield return (object)new WaitForSeconds(queued.PauseAfter); } } else { yield return null; } } else { if (cache._isLastBatch) { break; } yield return null; } queued = default(QueuedClip); } TTSCompanyBackend.WantedAudioClips.TryRemove(speakerHash, out var _); _activeCoroutines.Remove(speakerHash); } internal void CancelPlayback(CancelAudioTTS_NET data) { TTSCompanyNetworking.CancelClientTask(data._taskId); if (TTSCompanyBackend.WantedAudioClips.TryRemove(data._taskId, out var value)) { QueuedClip result; while (value._audioQueue.TryDequeue(out result)) { if ((Object)(object)result.Clip != (Object)null) { Object.Destroy((Object)(object)result.Clip); } } if ((Object)(object)value._foundNetworkObject != (Object)null) { TTSAudioSourceManager.StopAudioSource(value._foundNetworkObject, value._callingAssemblyHash); NetworkObject val = default(NetworkObject); if (value._foundNetworkObject.TryGetComponent(ref val)) { TTSCompanyBackend.SpeakingNetworkObjectIds.TryRemove(val.NetworkObjectId, out var _); } } } if (_activeCoroutines.TryGetValue(data._taskId, out var value3)) { if (value3 != null) { ((MonoBehaviour)this).StopCoroutine(value3); } _activeCoroutines.Remove(data._taskId); } } } } namespace TTSCompany.Components.Server.Components { internal sealed class ActiveTTSState { internal Coroutine Coroutine; internal CancellationTokenSource Cts; internal ulong NetworkObjectId; } internal sealed class BusyGeneration { internal readonly CancellationTokenSource Cts = new CancellationTokenSource(); internal readonly Task Task; private readonly object _lock = new object(); private int _waiterCount; private bool _finalized; internal BusyGeneration(Func> factory) { Task = factory(Cts.Token); } internal bool TryAddBusy() { lock (_lock) { if (_finalized) { return false; } _waiterCount++; return true; } } internal void RemoveBusy() { lock (_lock) { if (--_waiterCount <= 0) { _finalized = true; Cts.SafeCancel(); } } } } internal static class JSONHelper { internal static string Escape(string s) { if (string.IsNullOrEmpty(s)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(s.Length + 8); foreach (char c in s) { switch (c) { case '"': stringBuilder.Append("\\\""); continue; case '\\': stringBuilder.Append("\\\\"); continue; case '\n': stringBuilder.Append("\\n"); continue; case '\r': stringBuilder.Append("\\r"); continue; case '\t': stringBuilder.Append("\\t"); continue; case '\b': stringBuilder.Append("\\b"); continue; case '\f': stringBuilder.Append("\\f"); continue; } if (c < ' ') { StringBuilder stringBuilder2 = stringBuilder.Append("\\u"); int num = c; stringBuilder2.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static Dictionary ParseFlatObject(string json) { Dictionary dictionary = new Dictionary(); if (string.IsNullOrEmpty(json)) { return dictionary; } int i = 0; SkipWhitespace(json, ref i); Expect(json, ref i, '{'); SkipWhitespace(json, ref i); if (Peek(json, i) == '}') { i++; return dictionary; } while (true) { SkipWhitespace(json, ref i); string key = ParseString(json, ref i); SkipWhitespace(json, ref i); Expect(json, ref i, ':'); SkipWhitespace(json, ref i); object value = ParseValue(json, ref i); dictionary[key] = value; SkipWhitespace(json, ref i); switch (Peek(json, i)) { case ',': break; case '}': i++; return dictionary; default: throw new FormatException($"Unexpected character at position {i} in JSON: {json}"); } i++; } } private static object ParseValue(string json, ref int i) { switch (Peek(json, i)) { case '"': return ParseString(json, ref i); case 't': Expect(json, ref i, "true"); return true; case 'f': Expect(json, ref i, "false"); return false; case 'n': Expect(json, ref i, "null"); return null; default: return ParseNumber(json, ref i); } } private static string ParseString(string json, ref int i) { Expect(json, ref i, '"'); StringBuilder stringBuilder = new StringBuilder(); while (true) { char c = json[i++]; switch (c) { case '\\': { char c2 = json[i++]; switch (c2) { case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case '/': stringBuilder.Append('/'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': { int num = Convert.ToInt32(json.Substring(i, 4), 16); stringBuilder.Append((char)num); i += 4; break; } default: stringBuilder.Append(c2); break; } break; } default: stringBuilder.Append(c); break; case '"': return stringBuilder.ToString(); } } } private static object ParseNumber(string json, ref int i) { int num = i; while (i < json.Length && (char.IsDigit(json[i]) || json[i] == '-' || json[i] == '+' || json[i] == '.' || json[i] == 'e' || json[i] == 'E')) { i++; } string text = json.Substring(num, i - num); if (text.IndexOfAny(new char[3] { '.', 'e', 'E' }) >= 0) { return double.Parse(text, CultureInfo.InvariantCulture); } return long.Parse(text, CultureInfo.InvariantCulture); } private static void SkipWhitespace(string json, ref int i) { while (i < json.Length && char.IsWhiteSpace(json[i])) { i++; } } private static char Peek(string json, int i) { if (i >= json.Length) { return '\0'; } return json[i]; } private static void Expect(string json, ref int i, char c) { if (i >= json.Length || json[i] != c) { throw new FormatException($"Expected '{c}' at position {i} in JSON: {json}"); } i++; } private static void Expect(string json, ref int i, string token) { if (i + token.Length > json.Length || string.CompareOrdinal(json, i, token, 0, token.Length) != 0) { throw new FormatException($"Expected '{token}' at position {i} in JSON: {json}"); } i += token.Length; } } internal struct TTSRawResult { internal bool IsSuccess; internal bool IsCancelled; internal string Error; internal byte[] Pcm; internal int SampleRate; internal static TTSRawResult Ok(byte[] pcm, int sampleRate) { return new TTSRawResult { IsSuccess = true, Pcm = pcm, SampleRate = sampleRate }; } internal static TTSRawResult Failure(string error) { return new TTSRawResult { IsSuccess = false, Error = error }; } internal static TTSRawResult Cancelled() { return new TTSRawResult { IsSuccess = false, IsCancelled = true, Error = "Cancelled" }; } } internal sealed class VoiceModelMemoryManager { private struct MEMORYSTATUSEX { public uint dwLength; public uint dwMemoryLoad; public ulong ullTotalPhys; public ulong ullAvailPhys; public ulong ullTotalPageFile; public ulong ullAvailPageFile; public ulong ullTotalVirtual; public ulong ullAvailVirtual; public ulong ullAvailExtendedVirtual; } private readonly long _maxMemoryPoolBytes; private readonly long _fallbackModelSizeBytes = ConvertMBToLong(65); private readonly PiperTTSServer _piperServer; private readonly ConcurrentDictionary _modelLocations = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary _modelSizes = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary _modelLastAccess = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary> _modelAssemblies = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary _evictedModels = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); internal VoiceModelMemoryManager(PiperTTSServer piperServer) { _piperServer = piperServer ?? throw new ArgumentNullException("piperServer"); _maxMemoryPoolBytes = ConvertMBToLong(DetermineOptimalPoolSizeMegabytes()); } internal void InitializeModelRegistry() { string pluginPath = Paths.PluginPath; foreach (string item in FindVoiceModelFolders()) { string text = Path.Combine(pluginPath, item); foreach (FileInfo item2 in new DirectoryInfo(text).EnumerateFiles("*.onnx", SearchOption.TopDirectoryOnly)) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item2.Name); _modelSizes[fileNameWithoutExtension] = item2.Length; _modelLocations.TryAdd(fileNameWithoutExtension, Path.Combine(text, fileNameWithoutExtension + ".onnx")); LogConstants.VOICE_MODEL_MEM_MANAGER_FOUND_VOICE_MODEL_WITH_SIZE.Log("VoiceModelMemoryManager", fileNameWithoutExtension, item2.Length); } } } internal int GetAssemblyCountForModel(string modelName) { if (_modelAssemblies.TryGetValue(modelName, out var value)) { lock (value) { return value.Count; } } return 0; } internal bool HasVoiceModelBeenLoaded(string modelName) { return GetAssemblyCountForModel(modelName) > 0; } internal bool WasVoiceModelEvicted(string modelName) { return _evictedModels.ContainsKey(modelName); } internal bool IsVoiceModelValid(string modelName) { return _modelSizes.ContainsKey(modelName); } internal void UpdateLastUse(string modelName) { _modelLastAccess[modelName] = DateTime.UtcNow; } internal string GetRandomFoundTTSVoiceName() { int count = _modelLocations.Count; if (count == 0) { return null; } int num = Random.Range(0, count); int num2 = 0; foreach (KeyValuePair modelLocation in _modelLocations) { if (num2 == num) { return modelLocation.Key; } num2++; } return string.Empty; } internal string GetRandomLoadedTTSVoiceName() { int count = _modelAssemblies.Count; if (count == 0) { return null; } int num = Random.Range(0, count); int num2 = 0; foreach (KeyValuePair> modelAssembly in _modelAssemblies) { if (num2 == num) { return modelAssembly.Key; } num2++; } return string.Empty; } private string GetLoadModelString(string modelName, string voiceModelLocation) { return "{\"command\":\"load_model\",\"model\":\"" + JSONHelper.Escape(modelName) + "\",\"model_path\":\"" + JSONHelper.Escape(voiceModelLocation.TrimEnd('\\', '/')).Replace("\\", "\\\\") + "\",\"use_cuda\":false}\n"; } internal async Task<(bool Success, string Error)> ReloadModelAsync(string modelName, CancellationToken cancellationToken) { if (!_modelLocations.TryGetValue(modelName, out var voiceModelLocation)) { return (Success: false, Error: "Voice model file location value not found"); } UpdateLastUse(modelName); await EnforceDynamicMemoryLimitsAsync(modelName, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); Dictionary response = await _piperServer.SendSimpleCommandAsync(GetLoadModelString(modelName, voiceModelLocation), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); (bool, string) result = _piperServer.ToResult(response); if (result.Item1) { _evictedModels.TryRemove(modelName, out var _); LogConstants.PIPER_TTS_RELOADED_VOICE_MODEL.Log("VoiceModelMemoryManager", modelName); } return result; } internal async Task<(bool Success, string Error)> LoadModelAsync(string modelName, ulong callingAssemblyHash, CancellationToken cancellationToken) { if (!_modelLocations.TryGetValue(modelName, out var voiceModelLocation)) { return (Success: false, Error: "Voice model file location value not found"); } UpdateLastUse(modelName); HashSet assemblies = _modelAssemblies.GetOrAdd(modelName, (string _) => new HashSet()); bool flag; lock (assemblies) { if (_evictedModels.ContainsKey(modelName)) { flag = true; } else { if (assemblies.Contains(callingAssemblyHash)) { return (Success: true, Error: string.Empty); } flag = assemblies.Count == 0; } } if (!flag) { lock (assemblies) { assemblies.Add(callingAssemblyHash); } return (Success: true, Error: string.Empty); } await EnforceDynamicMemoryLimitsAsync(modelName, cancellationToken); Dictionary response = await _piperServer.SendSimpleCommandAsync(GetLoadModelString(modelName, voiceModelLocation), cancellationToken).ConfigureAwait(continueOnCapturedContext: false); (bool, string) result = _piperServer.ToResult(response); if (result.Item1) { _evictedModels.TryRemove(modelName, out var _); lock (assemblies) { assemblies.Add(callingAssemblyHash); } LogConstants.PIPER_TTS_LOADED_VOICE_MODEL.Log("VoiceModelMemoryManager", modelName); } else { lock (assemblies) { if (assemblies.Count == 0) { _modelAssemblies.TryRemove(modelName, out var _); } } LogConstants.PIPER_TTS_FAILED_LOADING_VOICE_MODEL.Log("VoiceModelMemoryManager", modelName); } return result; } internal async Task<(bool Success, string Error)> UnloadModelAsync(string modelName, ulong callingAssemblyHash, CancellationToken cancellationToken) { if (!_modelAssemblies.TryGetValue(modelName, out var assemblies)) { return (Success: true, Error: string.Empty); } lock (assemblies) { if (!assemblies.Contains(callingAssemblyHash)) { return (Success: true, Error: string.Empty); } if (assemblies.Count != 1) { assemblies.Remove(callingAssemblyHash); return (Success: true, Error: string.Empty); } } HashSet value2; DateTime value3; if (_evictedModels.TryRemove(modelName, out var _)) { lock (assemblies) { assemblies.Remove(callingAssemblyHash); if (assemblies.Count == 0) { _modelAssemblies.TryRemove(modelName, out value2); _modelLastAccess.TryRemove(modelName, out value3); } } return (Success: true, Error: string.Empty); } string requestJsonLine = "{\"command\":\"unload_model\",\"model\":\"" + JSONHelper.Escape(modelName) + "\"}\n"; Dictionary response = await _piperServer.SendSimpleCommandAsync(requestJsonLine, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); (bool, string) result = _piperServer.ToResult(response); if (result.Item1) { lock (assemblies) { assemblies.Remove(callingAssemblyHash); if (assemblies.Count == 0) { _modelAssemblies.TryRemove(modelName, out value2); _modelLastAccess.TryRemove(modelName, out value3); } } LogConstants.PIPER_TTS_UNLOADED_VOICE_MODEL.Log("VoiceModelMemoryManager", modelName); } else { LogConstants.PIPER_TTS_FAILED_UNLOADING_VOICE_MODEL.Log("VoiceModelMemoryManager", modelName); } return result; } private async Task EnforceDynamicMemoryLimitsAsync(string targetModelName, CancellationToken cancellationToken) { long value; long targetModelSize = (_modelSizes.TryGetValue(targetModelName, out value) ? value : _fallbackModelSizeBytes); long value2; while (_modelAssemblies.Keys.Where((string model) => !_evictedModels.ContainsKey(model)).Sum((string model) => (!_modelSizes.TryGetValue(model, out value2)) ? _fallbackModelSizeBytes : value2) + targetModelSize > _maxMemoryPoolBytes) { string text = (from kvp in _modelLastAccess where _modelAssemblies.ContainsKey(kvp.Key) && !_evictedModels.ContainsKey(kvp.Key) && !kvp.Key.Equals(targetModelName, StringComparison.OrdinalIgnoreCase) orderby kvp.Value select kvp.Key).FirstOrDefault(); if (string.IsNullOrEmpty(text)) { LogConstants.VOICE_MODEL_MEM_MANAGER_NO_MODEL_TO_EVICT.Log("VoiceModelMemoryManager", targetModelName); break; } LogConstants.VOICE_MODEL_MEM_MANAGER_POOL_LIMIT_REACHED.Log("VoiceModelMemoryManager", text); await ForceUnloadModelAsync(text, cancellationToken); } } private async Task ForceUnloadModelAsync(string modelName, CancellationToken cancellationToken) { string requestJsonLine = "{\"command\":\"unload_model\",\"model\":\"" + JSONHelper.Escape(modelName) + "\"}\n"; try { Dictionary response = await _piperServer.SendSimpleCommandAsync(requestJsonLine, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); if (_piperServer.ToResult(response).Success) { _evictedModels.TryAdd(modelName, value: true); return; } LogConstants.VOICE_MODEL_MEM_MANAGER_NO_MODEL_TO_EVICT.Log("VoiceModelMemoryManager", modelName); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("VoiceModelMemoryManager", "ForceUnloadModelAsync", ex.Message); } } private static long ConvertMBToLong(int valueInMb) { return (long)valueInMb * 1024L * 1024; } private static List FindVoiceModelFolders() { string pluginPath = Paths.PluginPath; List list = new List(); foreach (string item in Directory.EnumerateDirectories(pluginPath)) { string text = Path.Combine(item, "TTS-Company-Voices"); if (Directory.Exists(text)) { list.Add(text.Substring(pluginPath.Length).TrimStart(new char[1] { Path.DirectorySeparatorChar })); } } return list; } [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); private static int DetermineOptimalPoolSizeMegabytes() { MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX { dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)) }; if (GlobalMemoryStatusEx(ref lpBuffer)) { double num = (double)lpBuffer.ullTotalPhys / 1073741824.0; if (num <= 2.5) { return 512; } if (num <= 4.5) { return 1536; } if (num <= 8.5) { return 3072; } } return 4096; } } } namespace TTSCompany.Components.Networking { internal static class TTSCompanyNetworking { private const string message_PREFIX = ".msg_"; private const string messageId_SpawnTTSAudioSource_Server = "PixelIndieDev_TTSCompany.msg_SpawnTTSAudioSource_Server"; private const string messageId_SpawnTTSAudioSource_Clients = "PixelIndieDev_TTSCompany.msg_SpawnTTSAudioSource_Clients"; private const string messageId_UpdateTTSAudioSourceSettings_Server = "PixelIndieDev_TTSCompany.msg_UpdateTTSAudioSourceSettings_Server"; private const string messageId_UpdateTTSAudioSourceSettings_Clients = "PixelIndieDev_TTSCompany.msg_UpdateTTSAudioSourceSettings_Clients"; private const string messageId_DespawnTTSAudioSource_Server = "PixelIndieDev_TTSCompany.msg_DespawnTTSAudioSource_Server"; private const string messageId_DespawnTTSAudioSource_Clients = "PixelIndieDev_TTSCompany.msg_DespawnTTSAudioSource_Clients"; private const string messageId_SpeakTTS_Clients = "PixelIndieDev_TTSCompany.msg_SpeakTTS_Clients"; private const string messageId_SpeakTTS_Server = "PixelIndieDev_TTSCompany.msg_SpeakTTS_Server"; private const string messageId_SentenceProgress = "PixelIndieDev_TTSCompany.msg_SentenceProgress"; private const string messageId_PlaySpeakTTS = "PixelIndieDev_TTSCompany.msg_PlaySpeakTTS"; private const string messageId_CancelSpeakTTS = "PixelIndieDev_TTSCompany.msg_CancelSpeakTTS"; private static LNetworkMessage TTS_networkMessage_SpawnTTSAudioSource_Server; private static LNetworkMessage TTS_networkMessage_SpawnTTSAudioSource_Clients; private static LNetworkMessage TTS_networkMessage_UpdateTTSAudioSourceSettings_Server; private static LNetworkMessage TTS_networkMessage_UpdateTTSAudioSourceSettings_Clients; private static LNetworkMessage TTS_networkMessage_DespawnTTSAudioSource_Server; private static LNetworkMessage TTS_networkMessage_DespawnTTSAudioSource_Clients; private static LNetworkMessage TTS_networkMessage_SpeakTTS_Clients; private static LNetworkMessage TTS_networkMessage_SpeakTTS_Server; private static LNetworkMessage TTS_networkMessage_SentenceProgress; private static LNetworkMessage TTS_networkMessage_PlaySpeakTTS; private static LNetworkMessage TTS_networkMessage_CancelSpeakTTS; private static readonly ConcurrentDictionary ActiveTasks_Server = new ConcurrentDictionary(); private static ulong _nextSessionId_Speak = 0uL; private static readonly ConcurrentDictionary<(ulong NetworkObjectId, ulong CallingAssemblyHash), SpawnTTSAudioSource_NET> ActiveAudioSources_Server = new ConcurrentDictionary<(ulong, ulong), SpawnTTSAudioSource_NET>(); private static readonly ConcurrentDictionary ClientTasks = new ConcurrentDictionary(); internal static void Initialize() { TTS_networkMessage_SpawnTTSAudioSource_Server = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_SpawnTTSAudioSource_Server", (Action)SpawnTTSAudioSource, (Action)null, (Action)null); TTS_networkMessage_SpawnTTSAudioSource_Clients = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_SpawnTTSAudioSource_Clients", (Action)null, (Action)TTSAudioSourceManager.AddPermanentTTSAudioSource, (Action)null); TTS_networkMessage_UpdateTTSAudioSourceSettings_Server = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_UpdateTTSAudioSourceSettings_Server", (Action)UpdateTTSAudioSourceSettings, (Action)null, (Action)null); TTS_networkMessage_UpdateTTSAudioSourceSettings_Clients = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_UpdateTTSAudioSourceSettings_Clients", (Action)null, (Action)TTSAudioSourceManager.UpdateTTSAudioSourceSettings, (Action)null); TTS_networkMessage_DespawnTTSAudioSource_Server = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_DespawnTTSAudioSource_Server", (Action)DespawnTTSAudioSource, (Action)null, (Action)null); TTS_networkMessage_DespawnTTSAudioSource_Clients = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_DespawnTTSAudioSource_Clients", (Action)null, (Action)TTSAudioSourceManager.RemovePermanentTTSAudioSource, (Action)null); TTS_networkMessage_SpeakTTS_Clients = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_SpeakTTS_Clients", (Action)null, (Action)TTSCompanyBackend.SpeakTTSAtNetworkObject_OnClient, (Action)null); TTS_networkMessage_SpeakTTS_Server = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_SpeakTTS_Server", (Action)StartActiveTask, (Action)null, (Action)null); TTS_networkMessage_SentenceProgress = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_SentenceProgress", (Action)UpdateActiveTask, (Action)null, (Action)null); TTS_networkMessage_PlaySpeakTTS = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_PlaySpeakTTS", (Action)null, (Action)PlayTTS, (Action)null); TTS_networkMessage_CancelSpeakTTS = LNetworkMessage.Connect("PixelIndieDev_TTSCompany.msg_CancelSpeakTTS", (Action)null, (Action)TTSCompanyPlugin._ttsPlaybackManagerObject.CancelPlayback, (Action)null); } private static void SpawnTTSAudioSource(SpawnTTSAudioSource_NET data, ulong recievedFromPlayer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!LNetworkUtils.IsHostOrServer) { return; } ConcurrentDictionary<(ulong NetworkObjectId, ulong CallingAssemblyHash), SpawnTTSAudioSource_NET> activeAudioSources_Server = ActiveAudioSources_Server; NetworkObjectReference networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; activeAudioSources_Server[(((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId, data._callingAssemblyHash)] = data; try { TTS_networkMessage_SpawnTTSAudioSource_Clients.SendClients(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "SpawnTTSAudioSource", ex); } } private static void UpdateTTSAudioSourceSettings(UpdateTTSAudioSourceSettings_NET data, ulong recievedFromPlayer) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!LNetworkUtils.IsHostOrServer) { return; } (ulong, ulong) key = (((NetworkObjectReference)(ref data._networkObjectRefOfSpeaker)).NetworkObjectId, data._callingAssemblyHash); if (ActiveAudioSources_Server.TryGetValue(key, out var value)) { ActiveAudioSources_Server[key] = new SpawnTTSAudioSource_NET(value._networkObjectRefOfSpeaker, value._callingAssemblyHash, data._audioSourceSettings); } try { TTS_networkMessage_UpdateTTSAudioSourceSettings_Clients.SendClients(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "UpdateTTSAudioSourceSettings", ex); } } private static void DespawnTTSAudioSource(DespawnTTSAudioSource_NET data, ulong recievedFromPlayer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!LNetworkUtils.IsHostOrServer) { return; } ConcurrentDictionary<(ulong NetworkObjectId, ulong CallingAssemblyHash), SpawnTTSAudioSource_NET> activeAudioSources_Server = ActiveAudioSources_Server; NetworkObjectReference networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; activeAudioSources_Server.TryRemove((((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).NetworkObjectId, data._callingAssemblyHash), out var _); try { TTS_networkMessage_DespawnTTSAudioSource_Clients.SendClients(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "DespawnTTSAudioSource", ex); } } private static void UpdateActiveTask(SentenceProgressData_NET data, ulong recievedFromPlayer) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!LNetworkUtils.IsHostOrServer) { return; } LogConstants.TTS_COMPANY_NETWORKING_UPDATE_TASK.Log("TTSCompanyNetworking", recievedFromPlayer, data._sessionId); if (ActiveTasks_Server.TryGetValue(data._sessionId, out var value)) { bool[] value2; if (!data._success) { CancelAnyExistingSessionFor(value._speakingObject, value._callingAssemblyHash, "client failed generation"); } else if (value._completionList.TryGetValue(recievedFromPlayer, out value2)) { value2[data._textIndex] = data._success; CheckForFinishedTask(value); } } } private static void CheckForFinishedTask(TTSTask task) { int num = int.MaxValue; foreach (KeyValuePair snapshotClientId in task._snapshotClientIds) { if (LNetworkUtils.AllConnectedClients.Contains(snapshotClientId.Key) && task._completionList.TryGetValue(snapshotClientId.Key, out var value)) { int i; for (i = 0; i < value.Length && value[i]; i++) { } if (i < num) { num = i; } } } if (num == int.MaxValue || num <= task._lastStartSpeakingIndex) { return; } int num2 = num - task._lastStartSpeakingIndex; bool flag = num >= task._textsToSpeak.Length; if (num2 >= task._startSpeakingAtAmountOfFinishedTasks || flag) { int lastStartSpeakingIndex = task._lastStartSpeakingIndex; int endIndex = num - 1; try { TTS_networkMessage_PlaySpeakTTS.SendClients(new PlayAudioTTS_NET(task._taskId, lastStartSpeakingIndex, endIndex, flag)); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "TTS_networkMessage_PlaySpeakTTS.SendClients", ex); } task._lastStartSpeakingIndex = num; if (flag) { task._cts?.Dispose(); task._cts = null; StartServerPlaybackCleanupTimeout(task); } } } private static void StartServerPlaybackCleanupTimeout(TTSTask task) { if (!LNetworkUtils.IsHostOrServer) { return; } Task.Delay(TTSTimeoutHelper.GetPlaybackTimeout(task._textsToSpeak, task._voiceSettings)).ContinueWith(delegate { if (ActiveTasks_Server.TryRemove(task._taskId, out var _)) { LogConstants.TTS_COMPANY_NETWORKING_PLAYBACK_CLEANUP.Log("TTSCompanyNetworking", task._taskId); } }); } private static void StartActiveTask(TTSSpeakTTS_NET data, ulong recievedFromPlayer) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) if (LNetworkUtils.IsHostOrServer) { CancelAnyExistingSessionFor(data._networkObjectRefOfSpeaker, data._callingAssemblyHash, "Superseded by new session"); _nextSessionId_Speak++; ulong currentSessionId = _nextSessionId_Speak; TTSTask tTSTask = new TTSTask(LNetworkUtils.AllConnectedClients, data._textsToSpeak.Length) { _taskId = currentSessionId, _speakingObject = data._networkObjectRefOfSpeaker, _textsToSpeak = data._textsToSpeak, _callingAssemblyHash = data._callingAssemblyHash, _voiceSettings = data._voiceSettings, _textsWaited = 0, _cancelled = false, _cts = new CancellationTokenSource() }; TimeSpan generationTimeout = TTSTimeoutHelper.GetGenerationTimeout(data._textsToSpeak, data._voiceSettings); tTSTask._cts.Token.Register(delegate { HostCancelSession(currentSessionId, "Timed out"); }); tTSTask._cts.CancelAfter(generationTimeout); ActiveTasks_Server.TryAdd(currentSessionId, tTSTask); TTS_networkMessage_SpeakTTS_Clients.SendClients(new TTSSpeakTTS_PLUS_NET(data, currentSessionId)); } } private static void CancelAnyExistingSessionFor(NetworkObjectReference target, ulong callingAssemblyHash, string reason) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) TTSTask tTSTask = ActiveTasks_Server.Values.FirstOrDefault((TTSTask s) => !s._cancelled && s._callingAssemblyHash == callingAssemblyHash && ((NetworkObjectReference)(ref s._speakingObject)).NetworkObjectId == ((NetworkObjectReference)(ref target)).NetworkObjectId); if (tTSTask != null) { HostCancelSession(tTSTask._taskId, reason); } } private static void HostCancelSession(ulong sessionId, string reason) { if (!ActiveTasks_Server.TryGetValue(sessionId, out var value) || value._cancelled) { return; } value._cancelled = true; ActiveTasks_Server.TryRemove(sessionId, out var _); value._cts?.Dispose(); LogConstants.TTS_COMPANY_NETWORKING_TASK_CANCELLED.Log("TTSCompanyNetworking", sessionId, reason); try { TTS_networkMessage_CancelSpeakTTS.SendClients(new CancelAudioTTS_NET(sessionId, reason)); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "HostCancelSession", ex); } } private static void PlayTTS(PlayAudioTTS_NET playData) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (ClientTasks.TryGetValue(playData._taskId, out var value)) { int num = playData._endIndex - playData._startIndex + 1; AudioClip[] array = (AudioClip[])(object)new AudioClip[num]; float[] array2 = new float[num]; for (int i = playData._startIndex; i <= playData._endIndex; i++) { int num2 = i - playData._startIndex; array[num2] = value._generatedClips[i]; array2[num2] = value._pauseDurations[i]; value._generatedClips[i] = null; } TTSCompanyBackend.PlaySpeakTTSAtNetworkObject_OnClient(playData._taskId, value._networkObjectReference, value._callingAssemblyHash, array, array2, playData._isLastBatch); if (playData._endIndex >= value._generatedClips.Length - 1) { ClientTasks.TryRemove(playData._taskId, out var _); } } } internal static void Request_Server_SpawnTTSSource(SpawnTTSAudioSource_NET data) { try { TTS_networkMessage_SpawnTTSAudioSource_Server.SendServer(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "Request_Server_SpawnTTSSource", ex); } } internal static void Request_Server_UpdateTTSAudioSourceSettings(UpdateTTSAudioSourceSettings_NET data) { try { TTS_networkMessage_UpdateTTSAudioSourceSettings_Server.SendServer(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "Request_Server_UpdateTTSAudioSourceSettings", ex); } } internal static void Request_Server_DespawnTTSSource(DespawnTTSAudioSource_NET data) { try { TTS_networkMessage_DespawnTTSAudioSource_Server.SendServer(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "Request_Server_DespawnTTSSource", ex); } } internal static void Request_Server_SpeakTTS(TTSSpeakTTS_NET data) { try { TTS_networkMessage_SpeakTTS_Server.SendServer(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "Request_Server_SpeakTTS", ex); } } internal static void Request_Server_UpdateSentenceProgress(SentenceProgressData_NET data) { try { TTS_networkMessage_SentenceProgress.SendServer(data); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "Request_Server_UpdateSentenceProgress", ex); } } internal static void CreateClientTask(ulong taskId, NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash, string[] textsToSpeak, float sentenceSilence, float punctuationSilence, CancellationTokenSource cts) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (ClientTasks.TryRemove(taskId, out var value)) { value._cts.SafeCancel(); value._cts?.Dispose(); } float[] array = new float[textsToSpeak.Length]; for (int i = 0; i < textsToSpeak.Length; i++) { array[i] = TTSCompanyUtils.DetermineEndPause(textsToSpeak[i], sentenceSilence, punctuationSilence); } ClientTaskState value2 = new ClientTaskState { _sentences = textsToSpeak, _generatedClips = (AudioClip[])(object)new AudioClip[textsToSpeak.Length], _callingAssemblyHash = callingAssemblyHash, _pauseDurations = array, _cts = cts, _networkObjectReference = networkObjectRefOfSpeaker }; ClientTasks.TryAdd(taskId, value2); } internal static void UpdateClientTask(ulong taskId, int textIndex, AudioClip audioClip) { if (ClientTasks.TryGetValue(taskId, out var value) && (Object)(object)value._generatedClips[textIndex] == (Object)null) { value._generatedClips[textIndex] = audioClip; } } internal static void CancelClientTask(ulong taskId) { if (ClientTasks.TryRemove(taskId, out var value)) { value._cts.SafeCancel(); value._cts?.Dispose(); if (value._generatedClips != null) { Array.Clear(value._generatedClips, 0, value._generatedClips.Length); } } } internal static void SyncActiveAudioSourcesTo(ulong clientId) { if (!LNetworkUtils.IsHostOrServer) { return; } foreach (SpawnTTSAudioSource_NET value in ActiveAudioSources_Server.Values) { try { TTS_networkMessage_SpawnTTSAudioSource_Clients.SendClient(value, clientId); LogConstants.TTS_COMPANY_NETWORKING_SEND_AUDIO_SOURCES.Log("TTSCompanyNetworking", clientId); } catch (Exception ex) { LogConstants.CODE_GENERIC_EXCEPTION.Log("TTSCompanyNetworking", "SyncActiveAudioSourcesTo", ex); } } } internal static void HandlePlayerDisconnected(ulong clientId) { //IL_006d: 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) if (!LNetworkUtils.IsHostOrServer) { return; } foreach (TTSTask value4 in ActiveTasks_Server.Values) { value4._snapshotClientIds.TryRemove(clientId, out var _); value4._completionList.TryRemove(clientId, out var _); } NetworkObject val = default(NetworkObject); foreach (KeyValuePair<(ulong, ulong), SpawnTTSAudioSource_NET> item in ActiveAudioSources_Server) { NetworkObjectReference networkObjectRefOfSpeaker = item.Value._networkObjectRefOfSpeaker; if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { ActiveAudioSources_Server.TryRemove(item.Key, out var _); } } } internal static void ClearClientTasks() { foreach (ClientTaskState value in ClientTasks.Values) { value._cts?.SafeCancel(); value._cts?.Dispose(); if (value._generatedClips == null) { continue; } for (int i = 0; i < value._generatedClips.Length; i++) { if ((Object)(object)value._generatedClips[i] != (Object)null) { Object.Destroy((Object)(object)value._generatedClips[i]); value._generatedClips[i] = null; } } } ClientTasks.Clear(); } internal static void ClearServerTasks() { if (!LNetworkUtils.IsHostOrServer) { return; } foreach (TTSTask value in ActiveTasks_Server.Values) { value._cts?.SafeCancel(); value._cts?.Dispose(); } ActiveTasks_Server.Clear(); ActiveAudioSources_Server.Clear(); } } } namespace TTSCompany.Components.Networking.Components { internal sealed class ClientTaskState { internal string[] _sentences; internal AudioClip[] _generatedClips; internal ulong _callingAssemblyHash; internal float[] _pauseDurations; internal CancellationTokenSource _cts; internal NetworkObjectReference _networkObjectReference; } internal sealed class TTSTask { internal ulong _taskId; internal ulong _callingAssemblyHash; internal string[] _textsToSpeak; internal PiperVoiceSettings _voiceSettings; internal NetworkObjectReference _speakingObject; internal ConcurrentDictionary _snapshotClientIds; internal ConcurrentDictionary _completionList; internal int _textsWaited; internal int _amountOfTexts; internal int _startSpeakingAtAmountOfFinishedTasks; internal int _lastStartSpeakingIndex; internal bool _cancelled; internal CancellationTokenSource _cts; internal TTSTask(ulong[] expectedClients, int amountOfTexts) { _amountOfTexts = amountOfTexts - 1; _startSpeakingAtAmountOfFinishedTasks = Mathf.CeilToInt(Mathf.Clamp((float)amountOfTexts * 0.35f, 0f, 3f)); Dictionary collection = expectedClients.ToDictionary((ulong id) => id, (ulong id) => false); _snapshotClientIds = new ConcurrentDictionary(collection); Dictionary collection2 = expectedClients.ToDictionary((ulong id) => id, (ulong _) => new bool[amountOfTexts]); _completionList = new ConcurrentDictionary(collection2); } } } namespace TTSCompany.Components.Networking.Components.Structs { internal readonly struct CancelAudioTTS_NET { [SerializeField] internal readonly ulong _taskId; [SerializeField] internal readonly string _reason; internal CancelAudioTTS_NET(ulong taskId, string reason) { _taskId = taskId; _reason = reason; } } internal readonly struct DespawnTTSAudioSource_NET { [SerializeField] internal readonly NetworkObjectReference _networkObjectRefOfSpeaker; [SerializeField] internal readonly ulong _callingAssemblyHash; internal DespawnTTSAudioSource_NET(NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _networkObjectRefOfSpeaker = networkObjectRefOfSpeaker; _callingAssemblyHash = callingAssemblyHash; } } internal readonly struct PlayAudioTTS_NET { [SerializeField] internal readonly ulong _taskId; [SerializeField] internal readonly int _startIndex; [SerializeField] internal readonly int _endIndex; [SerializeField] internal readonly bool _isLastBatch; internal PlayAudioTTS_NET(ulong taskId, int startIndex, int endIndex, bool isLastBatch) { _taskId = taskId; _startIndex = startIndex; _endIndex = endIndex; _isLastBatch = isLastBatch; } } internal readonly struct QueuedClip { internal readonly AudioClip Clip; internal readonly float PauseAfter; internal QueuedClip(AudioClip clip, float pauseAfter) { Clip = clip; PauseAfter = pauseAfter; } } internal readonly struct SentenceProgressData_NET { [SerializeField] internal readonly ulong _sessionId; [SerializeField] internal readonly int _textIndex; [SerializeField] internal readonly bool _success; internal SentenceProgressData_NET(ulong sessionId, int textIndex, bool success) { _sessionId = sessionId; _textIndex = textIndex; _success = success; } } internal sealed class SpeakTTSAudioClipCache { internal GameObject _foundNetworkObject; internal ulong _callingAssemblyHash; internal ConcurrentQueue _audioQueue = new ConcurrentQueue(); private readonly ConcurrentDictionary _knownClips = new ConcurrentDictionary(); internal bool _isLastBatch; internal void MarkLastBatch() { _isLastBatch = true; } internal SpeakTTSAudioClipCache(GameObject foundNetworkObject, ulong callingAssemblyHash, AudioClip[] audioClips, float[] pauseDurations) { _foundNetworkObject = foundNetworkObject; _callingAssemblyHash = callingAssemblyHash; AddAudioClips(audioClips, pauseDurations); } internal void AddAudioClips(AudioClip[] audioClips, float[] pauseDurations) { for (int i = 0; i < audioClips.Length; i++) { AudioClip val = audioClips[i]; if (!((Object)(object)val == (Object)null) && _knownClips.TryAdd(val, value: false)) { float pauseAfter = ((pauseDurations != null && i < pauseDurations.Length) ? pauseDurations[i] : 0f); _audioQueue.Enqueue(new QueuedClip(val, pauseAfter)); } } } } internal readonly struct SpawnTTSAudioSource_NET { [SerializeField] internal readonly NetworkObjectReference _networkObjectRefOfSpeaker; [SerializeField] internal readonly ulong _callingAssemblyHash; [SerializeField] internal readonly TTSAudioSourceSettings _audioSourceSettings; internal SpawnTTSAudioSource_NET(NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _networkObjectRefOfSpeaker = networkObjectRefOfSpeaker; _callingAssemblyHash = callingAssemblyHash; _audioSourceSettings = audioSourceSettings; } } internal readonly struct TTSPregenerateTTS_NET { [SerializeField] internal readonly ulong _callingAssemblyHash; [SerializeField] internal readonly string[] _textsToSpeak; [SerializeField] internal readonly PiperVoiceSettings _voiceSettings; [SerializeField] internal readonly ulong _trackingKeyHash; internal TTSPregenerateTTS_NET(ulong callingAssemblyHash, string[] textToSpeak, PiperVoiceSettings voiceSettings, ulong trackingKeyHash) { _callingAssemblyHash = callingAssemblyHash; _textsToSpeak = textToSpeak; _voiceSettings = voiceSettings; _trackingKeyHash = trackingKeyHash; } } internal readonly struct TTSSpeakTTS_PLUS_NET { [SerializeField] internal readonly NetworkObjectReference _networkObjectRefOfSpeaker; [SerializeField] internal readonly ulong _callingAssemblyHash; [SerializeField] internal readonly string[] _textsToSpeak; [SerializeField] internal readonly PiperVoiceSettings _voiceSettings; [SerializeField] internal readonly ulong _trackingKeyHash; [SerializeField] internal readonly ulong _sessionId; internal TTSSpeakTTS_PLUS_NET(TTSSpeakTTS_NET nonLiteVersion, ulong sessionId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _networkObjectRefOfSpeaker = nonLiteVersion._networkObjectRefOfSpeaker; _textsToSpeak = nonLiteVersion._textsToSpeak; _voiceSettings = nonLiteVersion._voiceSettings; _trackingKeyHash = nonLiteVersion._trackingKeyHash; _callingAssemblyHash = nonLiteVersion._callingAssemblyHash; _sessionId = sessionId; } } internal readonly struct TTSSpeakTTS_NET { [SerializeField] internal readonly NetworkObjectReference _networkObjectRefOfSpeaker; [SerializeField] internal readonly ulong _callingAssemblyHash; [SerializeField] internal readonly string[] _textsToSpeak; [SerializeField] internal readonly PiperVoiceSettings _voiceSettings; [SerializeField] internal readonly ulong _trackingKeyHash; internal TTSSpeakTTS_NET(NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash, string[] textToSpeak, PiperVoiceSettings voiceSettings, ulong trackingKeyHash) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _networkObjectRefOfSpeaker = networkObjectRefOfSpeaker; _callingAssemblyHash = callingAssemblyHash; _textsToSpeak = textToSpeak; _voiceSettings = voiceSettings; _trackingKeyHash = trackingKeyHash; } } internal struct UpdateTTSAudioSourceSettings_NET { [SerializeField] internal NetworkObjectReference _networkObjectRefOfSpeaker; [SerializeField] internal ulong _callingAssemblyHash; [SerializeField] internal TTSAudioSourceSettings _audioSourceSettings; internal UpdateTTSAudioSourceSettings_NET(NetworkObjectReference networkObjectRefOfSpeaker, ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _networkObjectRefOfSpeaker = networkObjectRefOfSpeaker; _callingAssemblyHash = callingAssemblyHash; _audioSourceSettings = audioSourceSettings; } } } namespace TTSCompany.Components.Managers { internal static class TTSAudioSourceManager { private static readonly ConditionalWeakTable GameObjectWithTTSAudioSourcesComponent = new ConditionalWeakTable(); private static bool DoesGameObjectHaveTTSAudioSourcesComponent(GameObject networkObject, out TTSAudioSourcesComponent audioSourceContainingGameObject) { if ((Object)(object)networkObject == (Object)null || !Object.op_Implicit((Object)(object)networkObject)) { audioSourceContainingGameObject = null; return false; } return GameObjectWithTTSAudioSourcesComponent.TryGetValue(networkObject, out audioSourceContainingGameObject); } internal static void AddPermanentTTSAudioSource(SpawnTTSAudioSource_NET data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) NetworkObjectReference networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; NetworkObject val = default(NetworkObject); if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", data._networkObjectRefOfSpeaker); } else { AddPermanentTTSAudioSource(((Component)val).gameObject, data._callingAssemblyHash, data._audioSourceSettings); } } internal static bool AddPermanentTTSAudioSource(GameObject networkObject, ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { LogConstants.CODE_TRIGGERED.Log("TTSAudioSourceManager", "AddPermanentTTSAudioSource"); if ((Object)(object)networkObject == (Object)null) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("TTSAudioSourceManager", "AddPermanentTTSAudioSource", 1); return false; } if (!DoesGameObjectHaveTTSAudioSourcesComponent(networkObject, out var audioSourceContainingGameObject)) { audioSourceContainingGameObject = networkObject.AddComponent(); GameObjectWithTTSAudioSourcesComponent.Add(networkObject, audioSourceContainingGameObject); AddAudioSource(audioSourceContainingGameObject, callingAssemblyHash, audioSourceSettings); return true; } if (!audioSourceContainingGameObject.DoesAudioSourceExist(callingAssemblyHash)) { AddAudioSource(audioSourceContainingGameObject, callingAssemblyHash, audioSourceSettings); return true; } return false; } internal static void RemovePermanentTTSAudioSource(DespawnTTSAudioSource_NET data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) NetworkObjectReference networkObjectRefOfSpeaker = data._networkObjectRefOfSpeaker; NetworkObject val = default(NetworkObject); if (!((NetworkObjectReference)(ref networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", data._networkObjectRefOfSpeaker); } else { RemovePermanentTTSAudioSource(((Component)val).gameObject, data._callingAssemblyHash); } } internal static bool RemovePermanentTTSAudioSource(GameObject networkObject, ulong callingAssemblyHash) { LogConstants.CODE_TRIGGERED.Log("TTSAudioSourceManager", "RemovePermanentTTSAudioSource"); if ((Object)(object)networkObject == (Object)null) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("TTSAudioSourceManager", "RemovePermanentTTSAudioSource", 1); return false; } if (DoesGameObjectHaveTTSAudioSourcesComponent(networkObject, out var audioSourceContainingGameObject)) { return audioSourceContainingGameObject.RemoveAudioSource(callingAssemblyHash); } return false; } internal static bool PlayAudioSource(GameObject networkObject, ulong callingAssemblyHash, AudioClip audioClipToPlay) { LogConstants.CODE_TRIGGERED.Log("TTSAudioSourceManager", "PlayAudioSource"); if ((Object)(object)networkObject == (Object)null || (Object)(object)audioClipToPlay == (Object)null) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("TTSAudioSourceManager", "PlayAudioSource", 1); return false; } if (!DoesGameObjectHaveTTSAudioSourcesComponent(networkObject, out var audioSourceContainingGameObject)) { LogConstants.TTS_AUDIO_SOURCE_MANAGER_FAIL_PLAYING_NO_AUDIO_SOURCE.Log("TTSAudioSourceManager", "PlayAudioSource", ((Object)networkObject).name); return false; } return audioSourceContainingGameObject.PlayAudioClip(callingAssemblyHash, audioClipToPlay); } internal static bool StopAudioSource(GameObject networkObject, ulong callingAssemblyHash) { if (!DoesGameObjectHaveTTSAudioSourcesComponent(networkObject, out var audioSourceContainingGameObject)) { return false; } return audioSourceContainingGameObject.StopAudioClip(callingAssemblyHash); } private static void AddAudioSource(TTSAudioSourcesComponent audioSourceContainingGameObject, ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { if (audioSourceContainingGameObject.AddAudioSource(callingAssemblyHash)) { LogConstants.TTS_AUDIO_SOURCE_MANAGER_AUDIO_SOURCE_ADDED.Log("TTSAudioSourceManager", callingAssemblyHash); audioSourceContainingGameObject.UpdateAudioSourceSettings(callingAssemblyHash, audioSourceSettings); } } internal static void UpdateTTSAudioSourceSettings(UpdateTTSAudioSourceSettings_NET data) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) NetworkObject val = default(NetworkObject); if (!((NetworkObjectReference)(ref data._networkObjectRefOfSpeaker)).TryGet(ref val, (NetworkManager)null)) { LogConstants.API_NETWORK_OBJECT_NOT_FOUND.Log("TTSCompanyAPI", data._networkObjectRefOfSpeaker); } else { UpdateTTSAudioSourceSettings(((Component)val).gameObject, data._callingAssemblyHash, data._audioSourceSettings); } } internal static bool UpdateTTSAudioSourceSettings(GameObject networkObject, ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { if ((Object)(object)networkObject == (Object)null || audioSourceSettings == null) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("TTSAudioSourceManager", "UpdateTTSAudioSourceSettings", 1); return false; } if (!DoesGameObjectHaveTTSAudioSourcesComponent(networkObject, out var audioSourceContainingGameObject)) { LogConstants.CODE_INPUT_VARIABLES_INVALID.Log("TTSAudioSourceManager", "UpdateTTSAudioSourceSettings", 2); return false; } return audioSourceContainingGameObject.UpdateAudioSourceSettings(callingAssemblyHash, audioSourceSettings); } } } namespace TTSCompany.Components.Managers.Components { internal sealed class TTSAudioSourcesComponent : MonoBehaviour { private readonly ConcurrentDictionary audioSources = new ConcurrentDictionary(); internal bool AddAudioSource(ulong callingAssemblyHash) { if (!DoesAudioSourceExist(callingAssemblyHash)) { AudioSource value = ((Component)this).gameObject.AddComponent(); return audioSources.TryAdd(callingAssemblyHash, value); } return false; } internal bool DoesAudioSourceExist(ulong callingAssemblyHash) { return audioSources.ContainsKey(callingAssemblyHash); } internal bool GetAudioSource(ulong callingAssemblyHash, out AudioSource source) { return audioSources.TryGetValue(callingAssemblyHash, out source); } internal bool PlayAudioClip(ulong callingAssemblyHash, AudioClip newAudioClip) { LogConstants.CODE_TRIGGERED.Log("TTSAudioSourcesComponent", "PlayAudioClip"); if ((Object)(object)newAudioClip == (Object)null) { return false; } if (!GetAudioSource(callingAssemblyHash, out var source)) { return false; } AudioClip clip = source.clip; source.clip = newAudioClip; source.Play(); if ((Object)(object)clip != (Object)null && (Object)(object)clip != (Object)(object)newAudioClip) { Object.Destroy((Object)(object)clip); } return true; } internal bool StopAudioClip(ulong callingAssemblyHash) { if (!GetAudioSource(callingAssemblyHash, out var source)) { return false; } source.Stop(); if ((Object)(object)source.clip != (Object)null) { Object.Destroy((Object)(object)source.clip); } source.clip = null; return true; } internal bool UpdateAudioSourceSettings(ulong callingAssemblyHash, TTSAudioSourceSettings audioSourceSettings) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (!GetAudioSource(callingAssemblyHash, out var source)) { return false; } source.spatialize = false; source.spatializePostEffects = false; source.bypassEffects = audioSourceSettings.BypassEffects; source.bypassListenerEffects = audioSourceSettings.BypassListenerEffects; source.bypassReverbZones = audioSourceSettings.BypassReverbZones; source.playOnAwake = false; source.loop = false; source.priority = audioSourceSettings.Priority; source.volume = audioSourceSettings.Volume; source.spatialBlend = audioSourceSettings.SpatialBlend; source.reverbZoneMix = audioSourceSettings.ReverbZoneMix; source.dopplerLevel = audioSourceSettings.DopplerLevel; source.minDistance = audioSourceSettings.MinDistance; source.maxDistance = audioSourceSettings.MaxDistance; source.rolloffMode = audioSourceSettings.RolloffMode; source.outputAudioMixerGroup = audioSourceSettings.OutputAudioMixerGroup; if (audioSourceSettings.CustomCurve.HasValue) { (AudioSourceCurveType, AnimationCurve) value = audioSourceSettings.CustomCurve.Value; source.SetCustomCurve(value.Item1, value.Item2); } return true; } internal bool RemoveAudioSource(ulong callingAssemblyHash) { if (audioSources.TryRemove(callingAssemblyHash, out var value)) { Object.Destroy((Object)(object)value); return true; } return false; } private void OnDestroy() { foreach (AudioSource value in audioSources.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } audioSources.Clear(); } } } namespace TTSCompany.Components.Helpers { internal static class ClampHelper { internal static float ClampAndRound(float value, float min, float max) { return (float)Math.Round(Mathf.Clamp(value, min, max), 2, MidpointRounding.AwayFromZero); } } internal static class CtsHelper { internal static void SafeCancel(this CancellationTokenSource cts) { if (cts == null) { return; } try { cts.Cancel(); } catch (ObjectDisposedException) { LogConstants.CODE_GENERIC_CATCH.Log("CtsHelper", "SafeCancel"); } } } internal static class HashHelper { private const string GlobalCallerName = "TTSCompanyGlobalAudioSourceCaller"; internal static readonly ulong GlobalCallerHash = CalculateGlobalCallerHash(); private const ulong Prime = 1099511628211uL; private const ulong OffsetBasis = 14695981039346656037uL; private static readonly ConcurrentDictionary _assemblyHashCache = new ConcurrentDictionary(); internal static ulong GetTrackingKeyHash(ulong networkObjectId, Assembly callingAssembly) { ulong callingAssemblyHash = GetCallingAssemblyHash(callingAssembly); if (!_assemblyHashCache.TryGetValue(callingAssemblyHash, out var value)) { value = callingAssemblyHash; _assemblyHashCache.TryAdd(callingAssemblyHash, value); } CombineULong(ref value, networkObjectId); return value; } internal static ulong GetTrackingKeyHash(ulong networkObjectId) { if (!_assemblyHashCache.TryGetValue(GlobalCallerHash, out var value)) { value = GlobalCallerHash; _assemblyHashCache.TryAdd(GlobalCallerHash, value); } CombineULong(ref value, networkObjectId); return value; } internal static ulong GetTrackingKeyHash(string textToSpeak, PiperVoiceSettings settings) { ulong hash = 14695981039346656037uL; CombineString(ref hash, textToSpeak); if (settings != null) { CombineString(ref hash, settings.ModelName); CombineFloat(ref hash, settings.SpeechRate); CombineFloat(ref hash, settings.NoiseScale); CombineFloat(ref hash, settings.NoiseScaleW); CombineFloat(ref hash, settings.SentenceSilence); } return hash; } internal static ulong GetCallingAssemblyHash(Assembly callingAssembly) { ulong hash = 14695981039346656037uL; CombineString(ref hash, callingAssembly.GetName().Name); return hash; } internal static string GetHashTTSFileNameWithFileType(string textToSpeak, PiperVoiceSettings settings) { ulong hash = 14695981039346656037uL; CombineString(ref hash, textToSpeak); if (settings != null) { CombineString(ref hash, settings.ModelName); CombineFloat(ref hash, settings.SpeechRate); CombineFloat(ref hash, settings.NoiseScale); CombineFloat(ref hash, settings.NoiseScaleW); } return $"{hash:X16}.ogg"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void CombineString(ref ulong hash, string value) { if (!string.IsNullOrEmpty(value)) { foreach (uint num in value) { hash = (hash ^ (num & 0xFF)) * 1099511628211L; hash = (hash ^ (num >> 8)) * 1099511628211L; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void CombineFloat(ref ulong hash, float value) { uint num = Unsafe.As(ref value); hash = (hash ^ (num & 0xFF)) * 1099511628211L; hash = (hash ^ ((num >> 8) & 0xFF)) * 1099511628211L; hash = (hash ^ ((num >> 16) & 0xFF)) * 1099511628211L; hash = (hash ^ (num >> 24)) * 1099511628211L; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void CombineULong(ref ulong hash, ulong value) { hash = (hash ^ (value & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 8) & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 16) & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 24) & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 32) & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 40) & 0xFF)) * 1099511628211L; hash = (hash ^ ((value >> 48) & 0xFF)) * 1099511628211L; hash = (hash ^ (value >> 56)) * 1099511628211L; } private static ulong CalculateGlobalCallerHash() { ulong hash = 14695981039346656037uL; CombineString(ref hash, "TTSCompanyGlobalAudioSourceCaller"); return hash; } } internal static class TTSTimeoutHelper { private const float baseWordsPerSecond = 2.5f; private static readonly char[] wordSplitChars = new char[3] { ' ', '\r', '\n' }; internal static TimeSpan GetPlaybackTimeout(string[] textsToSpeak, PiperVoiceSettings settings) { TimeSpan timeSpan = TimeSpan.FromSeconds(4.0); if (textsToSpeak == null || textsToSpeak.Length == 0) { return timeSpan; } int num = 0; int num2 = 0; foreach (string text in textsToSpeak) { if (!string.IsNullOrWhiteSpace(text)) { num += text.Split(wordSplitChars, StringSplitOptions.RemoveEmptyEntries).Length; num2++; } } if (num == 0) { return timeSpan; } float num3 = ((settings.SpeechRate > 0.05f) ? settings.SpeechRate : 1f); float num4 = (float)num / 2.5f / num3; float num5 = (float)num2 * settings.SentenceSilence; TimeSpan timeSpan2 = TimeSpan.FromSeconds(num4 + num5 + TTSConstants.TTS_PLAYBACK_TIMEOUT_BUFFER_SECONDS_SCALED); if (!(timeSpan2 > timeSpan)) { return timeSpan; } return timeSpan2; } internal static TimeSpan GetGenerationTimeout(string[] textsToSpeak, PiperVoiceSettings settings) { TimeSpan timeSpan = TimeSpan.FromSeconds(4.0); if (textsToSpeak == null || textsToSpeak.Length == 0) { return timeSpan; } int num = 0; foreach (string text in textsToSpeak) { if (!string.IsNullOrWhiteSpace(text)) { num += text.Split(wordSplitChars, StringSplitOptions.RemoveEmptyEntries).Length; } } if (num == 0) { return timeSpan; } float num2 = ((settings.SpeechRate > 0.05f) ? settings.SpeechRate : 1f); float num3 = (float)num / 2.5f / num2 * TTSConstants.GetGenerationDurationScaling(); float num4 = (float)num * TTSConstants.TTS_TIMEOUT_PER_WORD_BUFFER_SCALED; TimeSpan timeSpan2 = TimeSpan.FromSeconds(num3 + num4 + TTSConstants.TTS_TIMEOUT_BASE_BUFFER_SCALED); if (!(timeSpan2 > timeSpan)) { return timeSpan; } return timeSpan2; } } internal static class VoiceHelper { internal static string CleanupVoiceModelname(string voiceModelname) { string text = ((voiceModelname != null && voiceModelname.EndsWith(".onnx", StringComparison.OrdinalIgnoreCase)) ? voiceModelname.Substring(0, voiceModelname.Length - 5) : voiceModelname); if (text != null) { return text; } return string.Empty; } } internal static class FolderHelper { internal static bool CheckForPiperTTS() { return File.Exists(TTSConstants.PIPER_EXECUTABLE_LOCATION); } internal static bool CheckForDefaultVoiceModels() { return Directory.Exists(TTSConstants.TTS_DEFAULT_VOICE_MODELS_FOLDER_LOCATION); } } } namespace TTSCompany.Components.Enums { internal enum TimeoutBufferScaling : byte { Low, Normal, High, Max } internal enum TTSGenPriority : byte { VeryLow, Low, Normal, High, Max } public enum TTSNetworkObjectState : byte { Invalid, Idle, GeneratingTTS, ActivelySpeaking } } namespace TTSCompany.Components.Constants { internal static class APIDefaultsConstants { internal const bool USE_GLOBAL_AUDIO_SOURCE = true; internal const PiperVoiceSettings PIPER_VOICE_SETTING_DEFAULT = null; internal const TTSAudioSourceSettings TTS_AUDIO_SOURCE_SETTING_DEFAULT = null; } internal static class ExampleConstants { internal const string VOICE_MODEL_NAME = "en_US-hfc_female-medium"; } internal static class OggConstants { internal const int OGG_BITRATE = 16000; internal const int OGG_SAMPLE_RATE = 24000; internal const int OGG_CHANNELS_AMOUNT = 1; } internal static class LogConstants { internal readonly struct LogMessage { internal string Message { get; } internal LogLevel Level { get; } internal LogMessage(LogLevel level, string message) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Level = level; Message = message; } internal void Log(params object[] args) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) logSource.Log(Level, (object)string.Format("{0} | " + Message, args)); } } internal static ManualLogSource logSource = Logger.CreateLogSource("PixelIndieDev_TTSCompany"); private const string DEFAULT_ERROR_LOG_PREFIX = "{0} | "; internal static readonly LogMessage CODE_TRIGGERED = new LogMessage((LogLevel)32, "{1} was triggered"); internal static readonly LogMessage CODE_INPUT_VARIABLES_INVALID = new LogMessage((LogLevel)32, "In {1}, check {2} found invalid variables"); internal static readonly LogMessage CODE_NEW_VALUE_SET = new LogMessage((LogLevel)32, "New value for {1} = {2}"); internal static readonly LogMessage CODE_GENERIC_CANCELLED = new LogMessage((LogLevel)32, "{1} was cancelled"); internal static readonly LogMessage CODE_GENERIC_EXCEPTION = new LogMessage((LogLevel)2, "{1} got exception: {2}"); internal static readonly LogMessage CODE_GENERIC_ERROR = new LogMessage((LogLevel)2, "{1} got error: {2}"); internal static readonly LogMessage CODE_GENERIC_CATCH = new LogMessage((LogLevel)4, "{1} was catched"); internal static readonly LogMessage CODE_GENERIC_FAIL = new LogMessage((LogLevel)2, "{1} failed with error: {2}"); internal static readonly LogMessage TTS_TIMEOUT_HELPER_TIMEOUT_INFO = new LogMessage((LogLevel)32, "textToSpeak = {1}, totalTimeoutInSeconds = {2}"); internal static readonly LogMessage TTS_GENERATOR_TTS_CANCELLED = new LogMessage((LogLevel)16, "TTS got cancelled for text: '{1}' with hash: '{2}'"); internal static readonly LogMessage TTS_GENERATOR_UNZIP_FAILED = new LogMessage((LogLevel)1, "{1} not found"); internal static readonly LogMessage TTS_GENERATOR_PROCESS_FAILED_TO_STOP = new LogMessage((LogLevel)2, "Process {1} failed to exit"); internal static readonly LogMessage TTS_GENERATOR_FAILED_TO_DELETE_0KB_CACHE = new LogMessage((LogLevel)2, "Failed to delete 0KB cache file with hash: '{1}' - {2}"); internal static readonly LogMessage TTS_GENERATOR_FFMPEG_EXITED_PREMATURE = new LogMessage((LogLevel)1, "FFmpeg exited prematurely"); internal static readonly LogMessage TTS_GENERATOR_NO_CACHED_AUDIO_FOUND = new LogMessage((LogLevel)2, "Cached audio file with hash: '{1}' not found at: {2}"); internal static readonly LogMessage TTS_GENERATOR_ARGUMENT_OUT_OF_RANGE_EX = new LogMessage((LogLevel)1, "MaxConcurrentRequests value must be at least 1"); internal static readonly LogMessage TTS_GENERATOR_FOUND_CACHED_TTS = new LogMessage((LogLevel)32, "Found {1} in cache"); internal static readonly LogMessage TTS_GENERATOR_GENERATING_TTS = new LogMessage((LogLevel)32, "Generating TTS for text: '{1}' with hash: '{2}'"); internal static readonly LogMessage TTS_GENERATOR_RUN_PIPER_ARGUMENTS = new LogMessage((LogLevel)32, "Arguments for {1} are: {2}"); internal static readonly LogMessage TTS_GENERATOR_DELETE_0KB_CACHE = new LogMessage((LogLevel)32, "Deleting 0KB cache file with hash: '{1}'"); internal static readonly LogMessage PLUGIN_LOADED = new LogMessage((LogLevel)16, "{1} + (version - {2}) : loaded successfully"); internal static readonly LogMessage PLUGIN_ON_QUIT = new LogMessage((LogLevel)16, "Game wants to quit, stopping background processes of {1} + (version - {2})"); internal static readonly LogMessage PLUGIN_TTS_COULD_NOT_BE_INITIALIZED = new LogMessage((LogLevel)1, "{1} could not be initialized"); internal static readonly LogMessage API_NETWORK_OBJECT_NOT_FOUND = new LogMessage((LogLevel)4, "NetworkObject {1} not found"); internal static readonly LogMessage API_TRIGGER_PRELOAD_VOICE_MODEL = new LogMessage((LogLevel)32, "Started preloading voice model: {1}"); internal static readonly LogMessage API_TRIGGER_UNLOAD_VOICE_MODEL = new LogMessage((LogLevel)32, "Started unloading voice model: {1}"); internal static readonly LogMessage PIPER_TTS_SERVER_SUCCESS_STARTUP = new LogMessage((LogLevel)16, "Started piper tts server on port {1} (pid {2})"); internal static readonly LogMessage PIPER_TTS_SERVER_STOPPED = new LogMessage((LogLevel)16, "Stopped piper tts server"); internal static readonly LogMessage PIPER_TTS_LOADED_VOICE_MODEL = new LogMessage((LogLevel)16, "Loaded voice model '{1}' using CPU"); internal static readonly LogMessage PIPER_TTS_UNLOADED_VOICE_MODEL = new LogMessage((LogLevel)16, "Unloaded voice model '{1}'"); internal static readonly LogMessage PIPER_TTS_FAILED_LOADING_VOICE_MODEL = new LogMessage((LogLevel)4, "Voice model '{1}' could not be loaded"); internal static readonly LogMessage PIPER_TTS_FAILED_UNLOADING_VOICE_MODEL = new LogMessage((LogLevel)4, "Voice model '{1}' could not be unloaded"); internal static readonly LogMessage PIPER_TTS_SERVER_EXE_NOT_FOUND = new LogMessage((LogLevel)1, "Server executable not found at: {1}"); internal static readonly LogMessage PIPER_TTS_SERVER_FAILED_TO_START = new LogMessage((LogLevel)1, "Failed to start piper tts server process with exception: {1}"); internal static readonly LogMessage PIPER_TTS_SERVER_VOICE_FOLDER_NOT_FOUND = new LogMessage((LogLevel)1, "Voice model directory not found at: {1}"); internal static readonly LogMessage PIPER_TTS_SERVER_STARTUP_ISSUE = new LogMessage((LogLevel)1, "Server process exited during startup (exit code {1} | stderr: {2})"); internal static readonly LogMessage PIPER_TTS_SERVER_OUTPUT_DRAIN = new LogMessage((LogLevel)4, "Piper tts server drain: {1}"); internal static readonly LogMessage PIPER_TTS_VOICE_MODEL_NOT_LOADED = new LogMessage((LogLevel)4, "Voice model '{1}' was not loaded beforehand as it has 0 assemblies that want it"); internal static readonly LogMessage PIPER_TTS_RELOADED_VOICE_MODEL = new LogMessage((LogLevel)32, "Reloaded voice model '{1}' using CPU"); internal static readonly LogMessage VOICE_MODEL_MEM_MANAGER_POOL_LIMIT_REACHED = new LogMessage((LogLevel)16, "Memory pool limit reached, unloaded {1}"); internal static readonly LogMessage VOICE_MODEL_MEM_MANAGER_NO_MODEL_TO_EVICT = new LogMessage((LogLevel)2, "Memory pool exceeded, but no models available to evict for {1}"); internal static readonly LogMessage VOICE_MODEL_MEM_MANAGER_FOUND_VOICE_MODEL_WITH_SIZE = new LogMessage((LogLevel)32, "Found voice model named: '{1}' with file size: '{2}'"); internal static readonly LogMessage TTS_AUDIO_SOURCE_MANAGER_FAIL_PLAYING_NO_AUDIO_SOURCE = new LogMessage((LogLevel)4, "{1} failed as no audio source was found on {2}"); internal static readonly LogMessage TTS_AUDIO_SOURCE_MANAGER_AUDIO_SOURCE_ADDED = new LogMessage((LogLevel)32, "Added audio source for caller with hash: {1}"); internal static readonly LogMessage TTS_COMPANY_NETWORKING_TASK_CANCELLED = new LogMessage((LogLevel)4, "Host cancelled session {1} with reason: {2}"); internal static readonly LogMessage TTS_COMPANY_NETWORKING_UPDATE_TASK = new LogMessage((LogLevel)32, "Player {1} send a task update for task {2}"); internal static readonly LogMessage TTS_COMPANY_NETWORKING_PLAYBACK_CLEANUP = new LogMessage((LogLevel)32, "Playback timeout cleaned up task {1}"); internal static readonly LogMessage TTS_COMPANY_NETWORKING_SEND_AUDIO_SOURCES = new LogMessage((LogLevel)32, "Send the audio sources to player with id: {1}"); } internal static class TTSConstants { internal static readonly string TTS_COMPANY_EXECUTABLE_LOCATION = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); internal const string PIPER_EXE_NAME = "piper-server.exe"; internal static readonly string PIPER_FOLDER_LOCATION = Path.Combine(TTS_COMPANY_EXECUTABLE_LOCATION, "PiperTTS"); internal static readonly string PIPER_EXECUTABLE_LOCATION = Path.Combine(PIPER_FOLDER_LOCATION, "piper-server.exe"); internal const int PIPER_SERVER_STARTUP_TIMEOUT_MS = 15000; internal const int PIPER_SERVER_REQUEST_TIMEOUT_MS = 30000; internal const int PIPER_SERVER_SHUTDOWN_TIMEOUT_MS = 2000; internal const string TTS_VOICE_MODELS_FOLDER = "TTS-Company-Voices"; internal static readonly string TTS_DEFAULT_VOICE_MODELS_FOLDER_LOCATION = Path.Combine(TTS_COMPANY_EXECUTABLE_LOCATION, "TTS-Company-Voices"); private const string TTS_VOICE_CACHE_SOUNDCLIPS_FOLDER = "TTS-Company-Voices-Cache"; internal static readonly string TTS_VOICE_CACHE_SOUNDCLIPS_PATH = Path.Combine(TTS_COMPANY_EXECUTABLE_LOCATION, "TTS-Company-Voices-Cache"); internal const float TTS_START_SPEAKING_AT_MULTIPLIER = 0.35f; internal const int TTS_MINIMUM_START_INDEX = 0; internal const int TTS_MAXIMUM_START_INDEX = 3; internal const float TTS_TIMEOUT_MINIMUM_TIME = 4f; private const float TTS_TIMEOUT_BASE_BUFFER = 4f; private const float TTS_TIMEOUT_PER_WORD_BUFFER = 0.05f; private const float TTS_PLAYBACK_TIMEOUT_BUFFER = 1.4f; internal static float TTS_TIMEOUT_BASE_BUFFER_SCALED = 0f; internal static float TTS_TIMEOUT_PER_WORD_BUFFER_SCALED = 0f; internal static float TTS_PLAYBACK_TIMEOUT_BUFFER_SECONDS_SCALED = 0f; internal const string TTS_SERVER_UNAVAILABLE = "TTS server is not available"; internal const string TTS_VOICE_MODEL_NAME_EMPTY = "voice model name must not be empty"; internal const string TTS_VALI_TEXT_TO_SPEAK = "TTS text cannot be empty"; internal const string TTS_VALI_SETTINGS = "PiperVoiceSettings cannot be NULL"; internal const string TTS_VALI_MODEL_NAME = "Voice model name must be set in settings"; internal const string TTS_VALI_MODEL_INVALID = "Piper voice model not found or valid"; internal const string TTS_VALI_SPEECH_RATE = "Speech rate must be > 0"; internal const string TTS_MEM_MANAGER_UNKNOWN_ASSEMBLY = "Could not determine calling assembly"; internal const string TTS_MEM_MANAGER_UNKNOWN_MODEL_LOCATION = "Voice model file location value not found"; internal const string DEBUG_AUDIOSOURCE_NAME = "DEBUG_KEYBIND"; internal static void UpdateTimeoutBuffers() { TTS_TIMEOUT_BASE_BUFFER_SCALED = 4f * GetTimeoutBufferScaling(isBase: true); TTS_TIMEOUT_PER_WORD_BUFFER_SCALED = 0.05f * GetTimeoutBufferScaling(isBase: false); TTS_PLAYBACK_TIMEOUT_BUFFER_SECONDS_SCALED = 1.4f * GetTimeoutBufferScaling(isBase: true); } private static float GetTimeoutBufferScaling(bool isBase) { switch (TTSCompanyPlugin.configEntryTimeoutBuffer.Value) { case TimeoutBufferScaling.Low: if (!isBase) { return 0.95f; } return 0.6f; default: if (!isBase) { return 1f; } return 1f; case TimeoutBufferScaling.High: if (!isBase) { return 1.1f; } return 1.4f; case TimeoutBufferScaling.Max: if (!isBase) { return 1.2f; } return 1.8f; } } internal static float GetGenerationDurationScaling() { return TTSCompanyPlugin.configEntryTimeoutBuffer.Value switch { TimeoutBufferScaling.Low => 0.95f, TimeoutBufferScaling.High => 1.4f, TimeoutBufferScaling.Max => 2f, _ => 1f, }; } } } [CompilerGenerated] internal sealed class <00d80ce5-5bcc-461d-924b-4968afa8f728> { [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 6)] internal struct __StaticArrayInitTypeSize=6 { } internal static readonly __StaticArrayInitTypeSize=6 3A8ECDCD5025B9256730F36816E7EE7D9322CD2E82B1AD5D31B4F00255156D42/* Not supported: data(2E 00 65 00 45 00) */; internal static readonly __StaticArrayInitTypeSize=6 631DD2A447570DAED0FB71936AA88BF84C797C036F13ED17901D2B0482D9884D/* Not supported: data(20 00 0D 00 0A 00) */; } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } namespace Concentus { internal interface IOpusDecoder : IDisposable { OpusBandwidth Bandwidth { get; } uint FinalRange { get; } int Gain { get; set; } int LastPacketDuration { get; } int NumChannels { get; } int Pitch { get; } int SampleRate { get; } int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false); int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false); void ResetState(); string GetVersionString(); } internal interface IOpusEncoder : IDisposable { OpusApplication Application { get; set; } int Bitrate { get; set; } int ForceChannels { get; set; } OpusBandwidth MaxBandwidth { get; set; } OpusBandwidth Bandwidth { get; set; } bool UseDTX { get; set; } int Complexity { get; set; } bool UseInbandFEC { get; set; } int PacketLossPercent { get; set; } bool UseVBR { get; set; } bool UseConstrainedVBR { get; set; } OpusSignal SignalType { get; set; } int Lookahead { get; } int SampleRate { get; } int NumChannels { get; } uint FinalRange { get; } int LSBDepth { get; set; } OpusFramesize ExpertFrameDuration { get; set; } OpusMode ForceMode { set; } bool PredictionDisabled { get; set; } int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes); int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes); void ResetState(); string GetVersionString(); } internal interface IOpusMultiStreamDecoder : IDisposable { OpusBandwidth Bandwidth { get; } uint FinalRange { get; } int Gain { get; set; } int LastPacketDuration { get; } int SampleRate { get; } int NumChannels { get; } int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec); int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec); void ResetState(); string GetVersionString(); } internal interface IOpusMultiStreamEncoder : IDisposable { OpusApplication Application { get; set; } OpusBandwidth Bandwidth { get; set; } int Bitrate { get; set; } int Complexity { get; set; } int NumChannels { get; } OpusFramesize ExpertFrameDuration { get; set; } uint FinalRange { get; } OpusMode ForceMode { set; } int Lookahead { get; } int LSBDepth { get; set; } OpusBandwidth MaxBandwidth { get; set; } int PacketLossPercent { get; set; } bool PredictionDisabled { get; set; } int SampleRate { get; } OpusSignal SignalType { get; set; } bool UseConstrainedVBR { get; set; } bool UseDTX { get; set; } bool UseInbandFEC { get; set; } bool UseVBR { get; set; } int EncodeMultistream(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes); int EncodeMultistream(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes); void ResetState(); string GetVersionString(); } internal interface IResampler : IDisposable { int InputLatency { get; } int InputStride { get; set; } int OutputLatencySamples { get; } TimeSpan OutputLatency { get; } int OutputStride { get; set; } int Quality { get; set; } void GetRateFraction(out int ratio_num, out int ratio_den); void GetRates(out int in_rate, out int out_rate); void ResetMem(); void SkipZeroes(); void Process(int channel_index, Span input, ref int in_len, Span output, ref int out_len); void Process(int channel_index, Span input, ref int in_len, Span output, ref int out_len); void ProcessInterleaved(Span input, ref int in_len, Span output, ref int out_len); void ProcessInterleaved(Span input, ref int in_len, Span output, ref int out_len); void SetRateFraction(int ratio_num, int ratio_den, int in_rate, int out_rate); void SetRates(int in_rate, int out_rate); } internal static class OpusCodecFactory { private static readonly object _mutex = new object(); private static bool _nativeLibInitialized = false; private static bool _isNativeLibAvailable = false; private static bool _userAllowNativeLib = true; public static bool AttemptToUseNativeLibrary { get { return _userAllowNativeLib; } set { _userAllowNativeLib = value; } } public static IOpusEncoder CreateEncoder(int sampleRate, int numChannels, OpusApplication application = OpusApplication.OPUS_APPLICATION_AUDIO, TextWriter messageLogger = null) { if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger)) { return NativeOpusEncoder.Create(sampleRate, numChannels, application); } return new OpusEncoder(sampleRate, numChannels, application); } public static IOpusDecoder CreateDecoder(int sampleRate, int numChannels, TextWriter messageLogger = null) { if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger)) { return NativeOpusDecoder.Create(sampleRate, numChannels); } return new OpusDecoder(sampleRate, numChannels); } public static IOpusMultiStreamEncoder CreateMultiStreamEncoder(int sampleRate, int numChannels, int mappingFamily, out int streams, out int coupledStreams, byte[] mapping, OpusApplication application, TextWriter messageLogger = null) { if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger)) { return NativeOpusMultistreamEncoder.Create(sampleRate, numChannels, mappingFamily, out streams, out coupledStreams, mapping, application); } return OpusMSEncoder.CreateSurround(sampleRate, numChannels, mappingFamily, out streams, out coupledStreams, mapping, application); } public static IOpusMultiStreamDecoder CreateMultiStreamDecoder(int sampleRate, int numChannels, int streams, int coupledStreams, byte[] mapping, TextWriter messageLogger = null) { if (_userAllowNativeLib && NativeLibraryAvailable(messageLogger)) { return NativeOpusMultistreamDecoder.Create(sampleRate, numChannels, streams, coupledStreams, mapping); } return new OpusMSDecoder(sampleRate, numChannels, streams, coupledStreams, mapping); } private static bool NativeLibraryAvailable(TextWriter messageLogger) { lock (_mutex) { if (!_nativeLibInitialized) { try { _isNativeLibAvailable = NativeOpus.Initialize(messageLogger); messageLogger?.WriteLine($"Is native opus available? {_isNativeLibAvailable}"); } catch (Exception ex) { messageLogger?.WriteLine(ex.ToString()); } _nativeLibInitialized = true; } return _isNativeLibAvailable; } } } internal static class Analysis { private const double M_PI = 3.141592653; private const float cA = 0.43157974f; private const float cB = 0.678484f; private const float cC = 0.08595542f; private const float cE = (float)Math.PI / 2f; private const int NB_TONAL_SKIP_BANDS = 9; internal static float fast_atan2f(float y, float x) { if (Inlines.ABS16(x) + Inlines.ABS16(y) < 1E-09f) { x *= 1E+12f; y *= 1E+12f; } float num = x * x; float num2 = y * y; if (num < num2) { float num3 = (num2 + 0.678484f * num) * (num2 + 0.08595542f * num); if (num3 != 0f) { return (0f - x) * y * (num2 + 0.43157974f * num) / num3 + ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)); } if (!(y < 0f)) { return (float)Math.PI / 2f; } return -(float)Math.PI / 2f; } float num4 = (num + 0.678484f * num2) * (num + 0.08595542f * num2); if (num4 != 0f) { return x * y * (num + 0.43157974f * num2) / num4 + ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)) - ((x * y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)); } return ((y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)) - ((x * y < 0f) ? (-(float)Math.PI / 2f) : ((float)Math.PI / 2f)); } internal static void tonality_analysis_init(TonalityAnalysisState tonal) { tonal.Reset(); } internal static void tonality_get_info(TonalityAnalysisState tonal, AnalysisInfo info_out, int len) { int num = tonal.read_pos; int num2 = tonal.write_pos - tonal.read_pos; if (num2 < 0) { num2 += 200; } if (len > 480 && num != tonal.write_pos) { num++; if (num == 200) { num = 0; } } if (num == tonal.write_pos) { num--; } if (num < 0) { num = 199; } info_out.Assign(tonal.info[num]); tonal.read_subframe += len / 120; while (tonal.read_subframe >= 4) { tonal.read_subframe -= 4; tonal.read_pos++; } if (tonal.read_pos >= 200) { tonal.read_pos -= 200; } num2 = Inlines.IMAX(num2 - 10, 0); float num3 = 0f; int i; for (i = 0; i < 200 - num2; i++) { num3 += tonal.pmusic[i]; } for (; i < 200; i++) { num3 += tonal.pspeech[i]; } num3 = num3 * tonal.music_confidence + (1f - num3) * tonal.speech_confidence; info_out.music_prob = num3; } internal static void tonality_analysis(TonalityAnalysisState tonal, CeltMode celt_mode, ReadOnlySpan x, int len, int offset, int c1, int c2, int C, int lsb_depth, Downmix.downmix_func downmix) { int num = 480; int num2 = 240; float[] angle = tonal.angle; float[] d_angle = tonal.d_angle; float[] d2_angle = tonal.d2_angle; float[] array = new float[18]; float[] array2 = new float[18]; float[] array3 = new float[8]; float[] array4 = new float[25]; float num3 = 97.40909f; float num4 = 0f; float[] array5 = new float[2]; int num5 = 0; float num6 = 0f; tonal.last_transition++; float num7 = 1f / (float)Inlines.IMIN(20, 1 + tonal.count); float num8 = 1f / (float)Inlines.IMIN(50, 1 + tonal.count); float num9 = 1f / (float)Inlines.IMIN(1000, 1 + tonal.count); if (tonal.count < 4) { tonal.music_prob = 0.5f; } FFTState st = celt_mode.mdct.kfft[0]; if (tonal.count == 0) { tonal.mem_fill = 240; } downmix(x, tonal.inmem, tonal.mem_fill, Inlines.IMIN(len, 720 - tonal.mem_fill), offset, c1, c2, C); if (tonal.mem_fill + len < 720) { tonal.mem_fill += len; return; } AnalysisInfo analysisInfo = tonal.info[tonal.write_pos++]; if (tonal.write_pos >= 200) { tonal.write_pos -= 200; } int[] array6 = new int[960]; int[] array7 = new int[960]; float[] array8 = new float[240]; float[] array9 = new float[240]; for (int i = 0; i < num2; i++) { float num10 = Tables.analysis_window[i]; array6[2 * i] = (int)(num10 * (float)tonal.inmem[i]); array6[2 * i + 1] = (int)(num10 * (float)tonal.inmem[num2 + i]); array6[2 * (num - i - 1)] = (int)(num10 * (float)tonal.inmem[num - i - 1]); array6[2 * (num - i - 1) + 1] = (int)(num10 * (float)tonal.inmem[num + num2 - i - 1]); } Arrays.MemMoveInt(tonal.inmem, 480, 0, 240); int num11 = len - (720 - tonal.mem_fill); downmix(x, tonal.inmem, 240, num11, offset + 720 - tonal.mem_fill, c1, c2, C); tonal.mem_fill = 240 + num11; KissFFT.opus_fft(st, array6, array7); for (int i = 1; i < num2; i++) { float x2 = (float)array7[2 * i] + (float)array7[2 * (num - i)]; float y = (float)array7[2 * i + 1] - (float)array7[2 * (num - i) + 1]; float x3 = (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1]; float y2 = (float)array7[2 * (num - i)] - (float)array7[2 * i]; float num12 = 1f / (2f * (float)Math.PI) * fast_atan2f(y, x2); float num13 = num12 - angle[i]; float num14 = num13 - d_angle[i]; float num15 = 1f / (2f * (float)Math.PI) * fast_atan2f(y2, x3); float num16 = num15 - num12; float num17 = num16 - num13; float num18 = num14 - (float)Math.Floor(0.5f + num14); array9[i] = Inlines.ABS16(num18); num18 *= num18; num18 *= num18; float num19 = num17 - (float)Math.Floor(0.5f + num17); array9[i] += Inlines.ABS16(num19); num19 *= num19; num19 *= num19; float num20 = 0.25f * (d2_angle[i] + 2f * num18 + num19); array8[i] = 1f / (1f + 640f * num3 * num20) - 0.015f; angle[i] = num15; d_angle[i] = num16; d2_angle[i] = num19; } float num21 = 0f; float num22 = 0f; analysisInfo.activity = 0f; float num23 = 0f; float num24 = 0f; if (tonal.count == 0) { for (int j = 0; j < 18; j++) { tonal.lowE[j] = 1E+10f; tonal.highE[j] = -1E+10f; } } float num25 = 0f; float num26 = 0f; for (int j = 0; j < 18; j++) { float num27 = 0f; float num28 = 0f; float num29 = 0f; for (int i = Tables.tbands[j]; i < Tables.tbands[j + 1]; i++) { float num30 = (float)array7[2 * i] * (float)array7[2 * i] + (float)array7[2 * (num - i)] * (float)array7[2 * (num - i)] + (float)array7[2 * i + 1] * (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1] * (float)array7[2 * (num - i) + 1]; num30 *= 5.55E-17f; num27 += num30; num28 += num30 * array8[i]; num29 += num30 * 2f * (0.5f - array9[i]); } tonal.E[tonal.E_count][j] = num27; num23 += num29 / (1E-15f + num27); num26 += (float)Math.Sqrt(num27 + 1E-10f); array2[j] = (float)Math.Log(num27 + 1E-10f); tonal.lowE[j] = Inlines.MIN32(array2[j], tonal.lowE[j] + 0.01f); tonal.highE[j] = Inlines.MAX32(array2[j], tonal.highE[j] - 0.1f); if (tonal.highE[j] < tonal.lowE[j] + 1f) { tonal.highE[j] += 0.5f; tonal.lowE[j] -= 0.5f; } num25 += (array2[j] - tonal.lowE[j]) / (1E-15f + tonal.highE[j] - tonal.lowE[j]); float num32; float num31 = (num32 = 0f); for (int i = 0; i < 8; i++) { num31 += (float)Math.Sqrt(tonal.E[i][j]); num32 += tonal.E[i][j]; } float num33 = Inlines.MIN16(0.99f, num31 / (float)Math.Sqrt(1E-15 + (double)(8f * num32))); num33 *= num33; num33 *= num33; num24 += num33; array[j] = Inlines.MAX16(num28 / (1E-15f + num27), num33 * tonal.prev_band_tonality[j]); num21 += array[j]; if (j >= 9) { num21 -= array[j - 18 + 9]; } num22 = Inlines.MAX16(num22, (1f + 0.03f * (float)(j - 18)) * num21); num4 += array[j] * (float)(j - 8); tonal.prev_band_tonality[j] = array[j]; } float num34 = 0f; num5 = 0; num6 = 0f; float num35 = 0.00057f / (float)(1 << Inlines.IMAX(0, lsb_depth - 8)); num35 *= 134217730f; num35 *= num35; for (int j = 0; j < 21; j++) { float num36 = 0f; int num37 = Tables.extra_bands[j]; int num38 = Tables.extra_bands[j + 1]; for (int i = num37; i < num38; i++) { float num39 = (float)array7[2 * i] * (float)array7[2 * i] + (float)array7[2 * (num - i)] * (float)array7[2 * (num - i)] + (float)array7[2 * i + 1] * (float)array7[2 * i + 1] + (float)array7[2 * (num - i) + 1] * (float)array7[2 * (num - i) + 1]; num36 += num39; } num6 = Inlines.MAX32(num6, num36); tonal.meanE[j] = Inlines.MAX32((1f - num9) * tonal.meanE[j], num36); num36 = Inlines.MAX32(num36, tonal.meanE[j]); num34 = Inlines.MAX32(0.05f * num34, num36); if ((double)num36 > 0.1 * (double)num34 && num36 * 1E+09f > num6 && num36 > num35 * (float)(num38 - num37)) { num5 = j; } } if (tonal.count <= 2) { num5 = 20; } num26 = 20f * (float)Math.Log10(num26); tonal.Etracker = Inlines.MAX32(tonal.Etracker - 0.03f, num26); tonal.lowECount *= 1f - num8; if (num26 < tonal.Etracker - 30f) { tonal.lowECount += num8; } for (int i = 0; i < 8; i++) { float num40 = 0f; for (int j = 0; j < 16; j++) { num40 += Tables.dct_table[i * 16 + j] * array2[j]; } array3[i] = num40; } num24 /= 18f; num25 /= 18f; if (tonal.count < 10) { num25 = 0.5f; } num23 /= 18f; analysisInfo.activity = num23 + (1f - num23) * num25; num21 = num22 / 9f; num21 = (tonal.prev_tonality = Inlines.MAX16(num21, tonal.prev_tonality * 0.8f)); num4 /= 64f; analysisInfo.tonality_slope = num4; tonal.E_count = (tonal.E_count + 1) % 8; tonal.count++; analysisInfo.tonality = num21; for (int i = 0; i < 4; i++) { array4[i] = -0.12299f * (array3[i] + tonal.mem[i + 24]) + 0.49195f * (tonal.mem[i] + tonal.mem[i + 16]) + 0.69693f * tonal.mem[i + 8] - 1.4349f * tonal.cmean[i]; } for (int i = 0; i < 4; i++) { tonal.cmean[i] = (1f - num7) * tonal.cmean[i] + num7 * array3[i]; } for (int i = 0; i < 4; i++) { array4[4 + i] = 0.63246f * (array3[i] - tonal.mem[i + 24]) + 0.31623f * (tonal.mem[i] - tonal.mem[i + 16]); } for (int i = 0; i < 3; i++) { array4[8 + i] = 0.53452f * (array3[i] + tonal.mem[i + 24]) - 0.26726f * (tonal.mem[i] + tonal.mem[i + 16]) - 0.53452f * tonal.mem[i + 8]; } if (tonal.count > 5) { for (int i = 0; i < 9; i++) { tonal.std[i] = (1f - num7) * tonal.std[i] + num7 * array4[i] * array4[i]; } } for (int i = 0; i < 8; i++) { tonal.mem[i + 24] = tonal.mem[i + 16]; tonal.mem[i + 16] = tonal.mem[i + 8]; tonal.mem[i + 8] = tonal.mem[i]; tonal.mem[i] = array3[i]; } for (int i = 0; i < 9; i++) { array4[11 + i] = (float)Math.Sqrt(tonal.std[i]); } array4[20] = analysisInfo.tonality; array4[21] = analysisInfo.activity; array4[22] = num24; array4[23] = analysisInfo.tonality_slope; array4[24] = tonal.lowECount; MultiLayerPerceptron.mlp_process(Tables.net, array4, array5); array5[0] = 0.5f * (array5[0] + 1f); array5[0] = 0.01f + 1.21f * array5[0] * array5[0] - 0.23f * (float)Math.Pow(array5[0], 10.0); array5[1] = 0.5f * array5[1] + 0.5f; array5[0] = array5[1] * array5[0] + (1f - array5[1]) * 0.5f; float num41 = 5E-05f * array5[1]; float num42 = 0.05f; float num43 = Inlines.MAX16(0.05f, Inlines.MIN16(0.95f, array5[0])); float num44 = Inlines.MAX16(0.05f, Inlines.MIN16(0.95f, tonal.music_prob)); num42 = 0.01f + 0.05f * Inlines.ABS16(num43 - num44) / (num43 * (1f - num44) + num44 * (1f - num43)); float num45 = (1f - tonal.music_prob) * (1f - num41) + tonal.music_prob * num41; float num46 = tonal.music_prob * (1f - num41) + (1f - tonal.music_prob) * num41; num45 *= (float)Math.Pow(1f - array5[0], num42); num46 *= (float)Math.Pow(array5[0], num42); tonal.music_prob = num46 / (num45 + num46); analysisInfo.music_prob = tonal.music_prob; float num47 = 1E-20f; float num48 = (float)Math.Pow(1f - array5[0], num42); float num49 = (float)Math.Pow(array5[0], num42); if (tonal.count == 1) { tonal.pspeech[0] = 0.5f; tonal.pmusic[0] = 0.5f; } float num50 = tonal.pspeech[0] + tonal.pspeech[1]; float num51 = tonal.pmusic[0] + tonal.pmusic[1]; tonal.pspeech[0] = num50 * (1f - num41) * num48; tonal.pmusic[0] = num51 * (1f - num41) * num49; for (int i = 1; i < 199; i++) { tonal.pspeech[i] = tonal.pspeech[i + 1] * num48; tonal.pmusic[i] = tonal.pmusic[i + 1] * num49; } tonal.pspeech[199] = num51 * num41 * num48; tonal.pmusic[199] = num50 * num41 * num49; for (int i = 0; i < 200; i++) { num47 += tonal.pspeech[i] + tonal.pmusic[i]; } num47 = 1f / num47; for (int i = 0; i < 200; i++) { tonal.pspeech[i] *= num47; tonal.pmusic[i] *= num47; } num47 = tonal.pmusic[0]; for (int i = 1; i < 200; i++) { num47 += tonal.pspeech[i]; } if ((double)array5[1] > 0.75) { if ((double)tonal.music_prob > 0.9) { float num52 = 1f / (float)(++tonal.music_confidence_count); tonal.music_confidence_count = Inlines.IMIN(tonal.music_confidence_count, 500); tonal.music_confidence += num52 * Inlines.MAX16(-0.2f, array5[0] - tonal.music_confidence); } if ((double)tonal.music_prob < 0.1) { float num53 = 1f / (float)(++tonal.speech_confidence_count); tonal.speech_confidence_count = Inlines.IMIN(tonal.speech_confidence_count, 500); tonal.speech_confidence += num53 * Inlines.MIN16(0.2f, array5[0] - tonal.speech_confidence); } } else { if (tonal.music_confidence_count == 0) { tonal.music_confidence = 0.9f; } if (tonal.speech_confidence_count == 0) { tonal.speech_confidence = 0.1f; } } if (tonal.last_music != ((tonal.music_prob > 0.5f) ? 1 : 0)) { tonal.last_transition = 0; } tonal.last_music = ((tonal.music_prob > 0.5f) ? 1 : 0); analysisInfo.bandwidth = num5; analysisInfo.noisiness = num23; analysisInfo.valid = 1; } internal static void run_analysis(TonalityAnalysisState analysis, CeltMode celt_mode, ReadOnlySpan analysis_pcm, int analysis_frame_size, int frame_size, int c1, int c2, int C, int Fs, int lsb_depth, Downmix.downmix_func downmix, AnalysisInfo analysis_info) { if (!analysis_pcm.IsEmpty) { analysis_frame_size = Inlines.IMIN(195 * Fs / 100, analysis_frame_size); int num = analysis_frame_size - analysis.analysis_offset; int num2 = analysis.analysis_offset; do { tonality_analysis(analysis, celt_mode, analysis_pcm, Inlines.IMIN(480, num), num2, c1, c2, C, lsb_depth, downmix); num2 += 480; num -= 480; } while (num > 0); analysis.analysis_offset = analysis_frame_size; analysis.analysis_offset -= frame_size; } analysis_info.valid = 0; tonality_get_info(analysis, analysis_info, frame_size); } } internal static class CodecHelpers { private const int MAX_DYNAMIC_FRAMESIZE = 24; internal static byte gen_toc(OpusMode mode, int framerate, OpusBandwidth bandwidth, int channels) { int num = 0; while (framerate < 400) { framerate <<= 1; num++; } byte b; switch (mode) { case OpusMode.MODE_SILK_ONLY: b = (byte)((int)(bandwidth - 1101) << 5); b |= (byte)(num - 2 << 3); break; case OpusMode.MODE_CELT_ONLY: { int num2 = (int)(bandwidth - 1102); if (num2 < 0) { num2 = 0; } b = 128; b |= (byte)(num2 << 5); b |= (byte)(num << 3); break; } default: b = 96; b |= (byte)((int)(bandwidth - 1104) << 4); b |= (byte)(num - 2 << 3); break; } return (byte)(b | (byte)(((channels == 2) ? 1u : 0u) << 2)); } internal static void hp_cutoff(ReadOnlySpan input, int input_ptr, int cutoff_Hz, Span output, int output_ptr, int[] hp_mem, int len, int channels, int Fs) { int[] array = new int[3]; int[] array2 = new int[2]; int num = Inlines.silk_DIV32_16(Inlines.silk_SMULBB(2471, cutoff_Hz), Fs / 1000); int num2 = (array[0] = 268435456 - Inlines.silk_MUL(471, num)); array[1] = Inlines.silk_LSHIFT(-num2, 1); array[2] = num2; int num3 = Inlines.silk_RSHIFT(num2, 6); array2[0] = Inlines.silk_SMULWW(num3, Inlines.silk_SMULWW(num, num) - 8388608); array2[1] = Inlines.silk_SMULWW(num3, num3); Filters.silk_biquad_alt(input, input_ptr, array, array2, hp_mem, 0, output, output_ptr, len, channels); if (channels == 2) { Filters.silk_biquad_alt(input, input_ptr + 1, array, array2, hp_mem, 2, output, output_ptr + 1, len, channels); } } internal static void dc_reject(ReadOnlySpan input, int input_ptr, int cutoff_Hz, Span output, int output_ptr, int[] hp_mem, int len, int channels, int Fs) { int shift = Inlines.celt_ilog2(Fs / (cutoff_Hz * 3)); for (int i = 0; i < channels; i++) { for (int j = 0; j < len; j++) { int num = Inlines.SHL32(Inlines.EXTEND32(input[channels * j + i + input_ptr]), 15); int num2 = num - hp_mem[2 * i]; hp_mem[2 * i] += Inlines.PSHR32(num - hp_mem[2 * i], shift); int a = num2 - hp_mem[2 * i + 1]; hp_mem[2 * i + 1] += Inlines.PSHR32(num2 - hp_mem[2 * i + 1], shift); output[channels * j + i + output_ptr] = Inlines.EXTRACT16(Inlines.SATURATE(Inlines.PSHR32(a, 15), 32767)); } } } internal static void stereo_fade(short[] pcm_buf, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs) { int num = 48000 / Fs; int num2 = overlap48 / num; g1 = 32767 - g1; g2 = 32767 - g2; int i; for (i = 0; i < num2; i++) { int num3 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]); int a = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num3, g2), 32767 - num3, g1), 15); int b = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1])); b = Inlines.MULT16_16_Q15(a, b); pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - b); pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + b); } for (; i < frame_size; i++) { int b2 = Inlines.EXTRACT16(Inlines.HALF32(pcm_buf[i * channels] - pcm_buf[i * channels + 1])); b2 = Inlines.MULT16_16_Q15(g2, b2); pcm_buf[i * channels] = (short)(pcm_buf[i * channels] - b2); pcm_buf[i * channels + 1] = (short)(pcm_buf[i * channels + 1] + b2); } } internal static void gain_fade(short[] buffer, int buf_ptr, int g1, int g2, int overlap48, int frame_size, int channels, int[] window, int Fs) { int num = 48000 / Fs; int num2 = overlap48 / num; if (channels == 1) { for (int i = 0; i < num2; i++) { int num3 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]); int a = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num3, g2), 32767 - num3, g1), 15); buffer[buf_ptr + i] = (short)Inlines.MULT16_16_Q15(a, buffer[buf_ptr + i]); } } else { for (int i = 0; i < num2; i++) { int num4 = Inlines.MULT16_16_Q15(window[i * num], window[i * num]); int a2 = Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num4, g2), 32767 - num4, g1), 15); buffer[buf_ptr + i * 2] = (short)Inlines.MULT16_16_Q15(a2, buffer[buf_ptr + i * 2]); buffer[buf_ptr + i * 2 + 1] = (short)Inlines.MULT16_16_Q15(a2, buffer[buf_ptr + i * 2 + 1]); } } int num5 = 0; do { for (int i = num2; i < frame_size; i++) { buffer[buf_ptr + i * channels + num5] = (short)Inlines.MULT16_16_Q15(g2, buffer[buf_ptr + i * channels + num5]); } } while (++num5 < channels); } internal static float transient_boost(Span E, int E_ptr, float[] E_1, int LM, int maxM) { float num = 0f; float num2 = 0f; int num3 = Inlines.IMIN(maxM, (1 << LM) + 1); for (int i = E_ptr; i < num3 + E_ptr; i++) { num += E[i]; num2 += E_1[i]; } float num4 = num * num2 / (float)(num3 * num3); return Inlines.MIN16(1f, (float)Math.Sqrt(Inlines.MAX16(0f, 0.05f * (num4 - 2f)))); } internal static int transient_viterbi(float[] E, float[] E_1, int N, int frame_cost, int rate) { float[][] array = Arrays.InitTwoDimensionalArray(24, 16); int[][] array2 = Arrays.InitTwoDimensionalArray(24, 16); float num = ((rate < 80) ? 0f : ((rate <= 160) ? (((float)rate - 80f) / 80f) : 1f)); for (int i = 0; i < 16; i++) { array2[0][i] = -1; array[0][i] = 1E+10f; } for (int i = 0; i < 4; i++) { array[0][1 << i] = (float)(frame_cost + rate * (1 << i)) * (1f + num * transient_boost(E, 0, E_1, i, N + 1)); array2[0][1 << i] = i; } for (int i = 1; i < N; i++) { for (int j = 2; j < 16; j++) { array[i][j] = array[i - 1][j - 1]; array2[i][j] = j - 1; } for (int j = 0; j < 4; j++) { array2[i][1 << j] = 1; float num2 = array[i - 1][1]; for (int k = 1; k < 4; k++) { float num3 = array[i - 1][(1 << k + 1) - 1]; if (num3 < num2) { array2[i][1 << j] = (1 << k + 1) - 1; num2 = num3; } } float num4 = (float)(frame_cost + rate * (1 << j)) * (1f + num * transient_boost(E, i, E_1, j, N - i + 1)); array[i][1 << j] = num2; if (N - i < 1 << j) { array[i][1 << j] += num4 * (float)(N - i) / (float)(1 << j); } else { array[i][1 << j] += num4; } } } int num5 = 1; float num6 = array[N - 1][1]; for (int i = 2; i < 16; i++) { if (array[N - 1][i] < num6) { num6 = array[N - 1][i]; num5 = i; } } for (int i = N - 1; i >= 0; i--) { num5 = array2[i][num5]; } return num5; } internal static int optimize_framesize(ReadOnlySpan x, int len, int C, int Fs, int bitrate, int tonality, float[] mem, int buffering, Downmix.downmix_func downmix) { float[] array = new float[28]; float[] array2 = new float[27]; int num = 0; int num2 = Fs / 400; int[] array3 = new int[num2]; array[0] = mem[0]; array2[0] = 1f / (1f + mem[0]); int num3; int num4; if (buffering != 0) { num3 = 2 * num2 - buffering; len -= num3; array[1] = mem[1]; array2[1] = 1f / (1f + mem[1]); array[2] = mem[2]; array2[2] = 1f / (1f + mem[2]); num4 = 3; } else { num4 = 1; num3 = 0; } int num5 = Inlines.IMIN(len / num2, 24); int num6 = 0; int i; for (i = 0; i < num5; i++) { float num7 = 1f; downmix(x, array3, 0, num2, i * num2 + num3, 0, -2, C); if (i == 0) { num6 = array3[0]; } for (int j = 0; j < num2; j++) { int num8 = array3[j]; num7 += (float)(num8 - num6) * (float)(num8 - num6); num6 = num8; } array[i + num4] = num7; array2[i + num4] = 1f / num7; } array[i + num4] = array[i + num4 - 1]; if (buffering != 0) { num5 = Inlines.IMIN(24, num5 + 2); } num = transient_viterbi(array, array2, num5, (int)((1f + 0.5f * (float)tonality) * (float)(60 * C + 40)), bitrate / 400); mem[0] = array[1 << num]; if (buffering != 0) { mem[1] = array[(1 << num) + 1]; mem[2] = array[(1 << num) + 2]; } return num; } internal static int frame_size_select(int frame_size, OpusFramesize variable_duration, int Fs) { if (frame_size < Fs / 400) { return -1; } int num; switch (variable_duration) { case OpusFramesize.OPUS_FRAMESIZE_ARG: num = frame_size; break; case OpusFramesize.OPUS_FRAMESIZE_VARIABLE: num = Fs / 50; break; case OpusFramesize.OPUS_FRAMESIZE_2_5_MS: case OpusFramesize.OPUS_FRAMESIZE_5_MS: case OpusFramesize.OPUS_FRAMESIZE_10_MS: case OpusFramesize.OPUS_FRAMESIZE_20_MS: case OpusFramesize.OPUS_FRAMESIZE_40_MS: case OpusFramesize.OPUS_FRAMESIZE_60_MS: num = Inlines.IMIN(3 * Fs / 50, Fs / 400 << (int)(variable_duration - 5001)); break; default: return -1; } if (num > frame_size) { return -1; } if (400 * num != Fs && 200 * num != Fs && 100 * num != Fs && 50 * num != Fs && 25 * num != Fs && 50 * num != 3 * Fs) { return -1; } return num; } internal static int compute_frame_size(ReadOnlySpan analysis_pcm, int frame_size, OpusFramesize variable_duration, int C, int Fs, int bitrate_bps, int delay_compensation, Downmix.downmix_func downmix, float[] subframe_mem, bool analysis_enabled) { if (analysis_enabled && variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs / 200) { int num = 3; num = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps, 0, subframe_mem, delay_compensation, downmix); while (Fs / 400 << num > frame_size) { num--; } frame_size = Fs / 400 << num; } else { frame_size = frame_size_select(frame_size, variable_duration, Fs); } if (frame_size < 0) { return -1; } return frame_size; } internal static int compute_stereo_width(ReadOnlySpan pcm, int pcm_ptr, int frame_size, int Fs, StereoWidthState mem) { int num = Fs / frame_size; int a = 32767 - 819175 / Inlines.IMAX(50, num); int num3; int num4; int num2 = (num3 = (num4 = 0)); for (int i = 0; i < frame_size - 3; i += 4) { int num5 = 0; int num6 = 0; int num7 = 0; int num8 = pcm_ptr + 2 * i; int num9 = pcm[num8]; int num10 = pcm[num8 + 1]; num5 = Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2); num6 = Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2); num7 = Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2); num9 = pcm[num8 + 2]; num10 = pcm[num8 + 3]; num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2); num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2); num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2); num9 = pcm[num8 + 4]; num10 = pcm[num8 + 5]; num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2); num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2); num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2); num9 = pcm[num8 + 6]; num10 = pcm[num8 + 7]; num5 += Inlines.SHR32(Inlines.MULT16_16(num9, num9), 2); num6 += Inlines.SHR32(Inlines.MULT16_16(num9, num10), 2); num7 += Inlines.SHR32(Inlines.MULT16_16(num10, num10), 2); num2 += Inlines.SHR32(num5, 10); num3 += Inlines.SHR32(num6, 10); num4 += Inlines.SHR32(num7, 10); } mem.XX += Inlines.MULT16_32_Q15(a, num2 - mem.XX); mem.XY += Inlines.MULT16_32_Q15(a, num3 - mem.XY); mem.YY += Inlines.MULT16_32_Q15(a, num4 - mem.YY); mem.XX = Inlines.MAX32(0, mem.XX); mem.XY = Inlines.MAX32(0, mem.XY); mem.YY = Inlines.MAX32(0, mem.YY); if (Inlines.MAX32(mem.XX, mem.YY) > 210) { int num11 = Inlines.celt_sqrt(mem.XX); int num12 = Inlines.celt_sqrt(mem.YY); int num13 = Inlines.celt_sqrt(num11); int num14 = Inlines.celt_sqrt(num12); mem.XY = Inlines.MIN32(mem.XY, num11 * num12); int num15 = Inlines.SHR32(Inlines.frac_div32(mem.XY, 1 + Inlines.MULT16_16(num11, num12)), 16); int b = 32767 * Inlines.ABS16(num13 - num14) / (1 + num13 + num14); int num16 = Inlines.MULT16_16_Q15(Inlines.celt_sqrt(1073741824 - Inlines.MULT16_16(num15, num15)), b); mem.smoothed_width += (num16 - mem.smoothed_width) / num; mem.max_follower = Inlines.MAX16(mem.max_follower - 655 / num, mem.smoothed_width); } else { int num16 = 0; int num15 = 32767; int b = 0; } return Inlines.EXTRACT16(Inlines.MIN32(32767, 20 * mem.max_follower)); } internal static void smooth_fade(Span in1, int in1_ptr, Span in2, int in2_ptr, Span output, int output_ptr, int overlap, int channels, int[] window, int Fs) { int num = 48000 / Fs; for (int i = 0; i < channels; i++) { for (int j = 0; j < overlap; j++) { int num2 = Inlines.MULT16_16_Q15(window[j * num], window[j * num]); output[output_ptr + j * channels + i] = (short)Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(num2, in2[in2_ptr + j * channels + i]), 32767 - num2, in1[in1_ptr + j * channels + i]), 15); } } } internal static string opus_strerror(int error) { string[] array = new string[8] { "success", "invalid argument", "buffer too small", "internal error", "corrupted stream", "request not implemented", "invalid state", "memory allocation failed" }; if (error > 0 || error < -7) { return "unknown error"; } return array[-error]; } internal static string GetVersionString() { return "Concentus 2.1.2"; } } internal static class Downmix { internal delegate void downmix_func(ReadOnlySpan _x, Span sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C); internal static void downmix_float(ReadOnlySpan x, Span sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C) { for (int i = 0; i < subframe; i++) { sub[sub_ptr + i] = Inlines.FLOAT2INT16(x[(i + offset) * C + c1]); } if (c2 > -1) { for (int i = 0; i < subframe; i++) { sub[sub_ptr + i] += Inlines.FLOAT2INT16(x[(i + offset) * C + c2]); } } else if (c2 == -2) { for (int j = 1; j < C; j++) { int num = j; for (int i = 0; i < subframe; i++) { sub[sub_ptr + i] += Inlines.FLOAT2INT16(x[(i + offset) * C + num]); } } } int num2 = 4096; num2 = ((C != -2) ? (num2 / 2) : (num2 / C)); for (int i = 0; i < subframe; i++) { sub[sub_ptr + i] *= num2; } } internal static void downmix_int(ReadOnlySpan x, Span sub, int sub_ptr, int subframe, int offset, int c1, int c2, int C) { for (int i = 0; i < subframe; i++) { sub[i + sub_ptr] = x[(i + offset) * C + c1]; } if (c2 > -1) { for (int i = 0; i < subframe; i++) { sub[i + sub_ptr] += x[(i + offset) * C + c2]; } } else if (c2 == -2) { for (int j = 1; j < C; j++) { for (int i = 0; i < subframe; i++) { sub[i + sub_ptr] += x[(i + offset) * C + j]; } } } int num = 4096; num = ((C != -2) ? (num / 2) : (num / C)); for (int i = 0; i < subframe; i++) { sub[i + sub_ptr] *= num; } } } internal static class MultiLayerPerceptron { private const int MAX_NEURONS = 100; internal static float tansig_approx(float x) { float num = 1f; if (!(x < 8f)) { return 1f; } if (!(x > -8f)) { return -1f; } if (x < 0f) { x = 0f - x; num = -1f; } int num2 = (int)Math.Floor(0.5f + 25f * x); x -= 0.04f * (float)num2; float num3 = Tables.tansig_table[num2]; float num4 = 1f - num3 * num3; num3 += x * num4 * (1f - num3 * x); return num * num3; } internal static void mlp_process(MLP m, float[] input, float[] output) { float[] array = new float[100]; float[] weights = m.weights; int num = 0; for (int i = 0; i < m.topo[1]; i++) { float num2 = weights[num]; num++; for (int j = 0; j < m.topo[0]; j++) { num2 += input[j] * weights[num]; num++; } array[i] = tansig_approx(num2); } for (int i = 0; i < m.topo[2]; i++) { float num3 = weights[num]; num++; for (int k = 0; k < m.topo[1]; k++) { num3 += array[k] * weights[num]; num++; } output[i] = tansig_approx(num3); } } } internal static class OpusCompare { private const int NBANDS = 21; private const int NFREQS = 240; private const int TEST_WIN_SIZE = 480; private const int TEST_WIN_STEP = 120; private static readonly int[] BANDS = new int[22] { 0, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 156, 200 }; private static void band_energy(Pointer _out, Pointer _ps, Pointer _bands, int _nbands, Pointer _in, int _nchannels, int _nframes, int _window_sz, int _step, int _downsample) { Pointer pointer = Concentus.Common.CPlusPlus.Pointer.Malloc((3 + _nchannels) * _window_sz); Pointer pointer2 = pointer.Point(_window_sz); Pointer pointer3 = pointer2.Point(_window_sz); Pointer pointer4 = pointer3.Point(_window_sz); int num = _window_sz / 2; for (int i = 0; i < _window_sz; i++) { pointer[i] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * 2.0 / (double)(_window_sz - 1) * (double)i)); } for (int i = 0; i < _window_sz; i++) { pointer2[i] = (float)Math.Cos(Math.PI * 2.0 / (double)_window_sz * (double)i); } for (int i = 0; i < _window_sz; i++) { pointer3[i] = (float)Math.Sin(Math.PI * 2.0 / (double)_window_sz * (double)i); } for (int j = 0; j < _nframes; j++) { for (int k = 0; k < _nchannels; k++) { for (int l = 0; l < _window_sz; l++) { pointer4[k * _window_sz + l] = pointer[l] * _in[(j * _step + l) * _nchannels + k]; } } int i; for (int m = (i = 0); m < _nbands; m++) { float[] array = new float[2]; for (; i < _bands[m + 1]; i++) { for (int k = 0; k < _nchannels; k++) { int num2 = 0; float num4; float num3 = (num4 = 0f); for (int l = 0; l < _window_sz; l++) { num3 += pointer2[num2] * pointer4[k * _window_sz + l]; num4 -= pointer3[num2] * pointer4[k * _window_sz + l]; num2 += i; if (num2 >= _window_sz) { num2 -= _window_sz; } } num3 *= (float)_downsample; num4 *= (float)_downsample; _ps[(j * num + i) * _nchannels + k] = num3 * num3 + num4 * num4 + 100000f; array[k] += _ps[(j * num + i) * _nchannels + k]; } } if (_out != null) { _out[(j * _nbands + m) * _nchannels] = array[0] / (float)(_bands[m + 1] - _bands[m]); if (_nchannels == 2) { _out[(j * _nbands + m) * _nchannels + 1] = array[1] / (float)(_bands[m + 1] - _bands[m]); } } } } } internal static float compare(float[] x, float[] y, int nchannels, int rate = 48000) { int num = x.Length; int num2 = y.Length; int num3 = 21; int num4 = 240; if (rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000) { throw new ArgumentException("Sampling rate must be 8000, 12000, 16000, 24000, or 48000\n"); } int num5; if (rate != 48000) { num5 = 48000 / rate; switch (rate) { case 8000: num3 = 13; break; case 12000: num3 = 15; break; case 16000: num3 = 17; break; case 24000: num3 = 19; break; } num4 = 240 / num5; } else { num5 = 1; } if (num != num2 * num5) { throw new ArgumentException("Sample counts do not match"); } if (num < 480) { throw new ArgumentException("Insufficient sample data"); } int num6 = (num - 480 + 120) / 120; Pointer pointer = Concentus.Common.CPlusPlus.Pointer.Malloc(num6 * 21 * nchannels); Pointer pointer2 = Concentus.Common.CPlusPlus.Pointer.Malloc(num6 * 240 * nchannels); Pointer pointer3 = Concentus.Common.CPlusPlus.Pointer.Malloc(num6 * num4 * nchannels); band_energy(pointer, pointer2, BANDS.GetPointer(), 21, x.GetPointer(), nchannels, num6, 480, 120, 1); band_energy(null, pointer3, BANDS.GetPointer(), num3, y.GetPointer(), nchannels, num6, 480 / num5, 120 / num5, num5); for (int i = 0; i < num6; i++) { int j; for (j = 1; j < 21; j++) { for (int k = 0; k < nchannels; k++) { pointer[(i * 21 + j) * nchannels + k] += 0.1f * pointer[(i * 21 + j - 1) * nchannels + k]; } } j = 20; while (j-- > 0) { for (int k = 0; k < nchannels; k++) { pointer[(i * 21 + j) * nchannels + k] += 0.03f * pointer[(i * 21 + j + 1) * nchannels + k]; } } if (i > 0) { for (j = 0; j < 21; j++) { for (int k = 0; k < nchannels; k++) { pointer[(i * 21 + j) * nchannels + k] += 0.5f * pointer[((i - 1) * 21 + j) * nchannels + k]; } } } if (nchannels == 2) { for (j = 0; j < 21; j++) { float num7 = pointer[(i * 21 + j) * nchannels]; float num8 = pointer[(i * 21 + j) * nchannels + 1]; pointer[(i * 21 + j) * nchannels] += 0.01f * num8; pointer[(i * 21 + j) * nchannels + 1] += 0.01f * num7; } } for (j = 0; j < num3; j++) { for (int l = BANDS[j]; l < BANDS[j + 1]; l++) { for (int k = 0; k < nchannels; k++) { pointer2[(i * 240 + l) * nchannels + k] += 0.1f * pointer[(i * 21 + j) * nchannels + k]; pointer3[(i * num4 + l) * nchannels + k] += 0.1f * pointer[(i * 21 + j) * nchannels + k]; } } } } for (int j = 0; j < num3; j++) { for (int l = BANDS[j]; l < BANDS[j + 1]; l++) { for (int k = 0; k < nchannels; k++) { float num9 = pointer2[l * nchannels + k]; float num10 = pointer3[l * nchannels + k]; for (int i = 1; i < num6; i++) { float num11 = pointer2[(i * 240 + l) * nchannels + k]; float num12 = pointer3[(i * num4 + l) * nchannels + k]; pointer2[(i * 240 + l) * nchannels + k] += num9; pointer3[(i * num4 + l) * nchannels + k] += num10; num9 = num11; num10 = num12; } } } } int num13 = rate switch { 48000 => BANDS[21], 12000 => BANDS[num3], _ => BANDS[num3] - 3, }; double num14 = 0.0; for (int i = 0; i < num6; i++) { double num15 = 0.0; for (int j = 0; j < num3; j++) { double num16 = 0.0; for (int l = BANDS[j]; l < BANDS[j + 1] && l < num13; l++) { for (int k = 0; k < nchannels; k++) { float num17 = pointer3[(i * num4 + l) * nchannels + k] / pointer2[(i * 240 + l) * nchannels + k]; float num18 = num17 - (float)Math.Log(num17) - 1f; if (l >= 79 && l <= 81) { num18 *= 0.1f; } if (l == 80) { num18 *= 0.1f; } num16 += (double)num18; } } num16 /= (double)((BANDS[j + 1] - BANDS[j]) * nchannels); num15 += num16 * num16; } num15 /= 21.0; num15 *= num15; num14 += num15 * num15; } num14 = Math.Pow(num14 / (double)num6, 0.0625); float result = (float)(100.0 * (1.0 - 0.5 * Math.Log(1.0 + num14) / Math.Log(1.13))); _ = 0f; return result; } } internal static class OpusConstants { internal const int OPUS_AUTO = -1000; internal const int OPUS_BITRATE_MAX = -1; internal const int NB_FRAMES = 8; internal const int NB_TBANDS = 18; internal const int NB_TOT_BANDS = 21; internal const int NB_TONAL_SKIP_BANDS = 9; internal const int ANALYSIS_BUF_SIZE = 720; internal const int DETECT_SIZE = 200; internal const int MAX_ENCODER_BUFFER = 480; } internal class OpusException : Exception { public int OpusErrorCode { get; private set; } internal OpusException() : base("Unknown error") { OpusErrorCode = -100; } internal OpusException(string message) : base(message) { OpusErrorCode = -100; } internal OpusException(int opusError) : base(CodecHelpers.opus_strerror(opusError)) { OpusErrorCode = opusError; } internal OpusException(string message, int opusError) : base(message) { OpusErrorCode = opusError; } } internal static class OpusMultistream { internal static int validate_layout(ChannelLayout layout) { int num = layout.nb_streams + layout.nb_coupled_streams; if (num > 255) { return 0; } for (int i = 0; i < layout.nb_channels; i++) { if (layout.mapping[i] >= num && layout.mapping[i] != byte.MaxValue) { return 0; } } return 1; } internal static int get_left_channel(ChannelLayout layout, int stream_id, int prev) { for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++) { if (layout.mapping[i] == stream_id * 2) { return i; } } return -1; } internal static int get_right_channel(ChannelLayout layout, int stream_id, int prev) { for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++) { if (layout.mapping[i] == stream_id * 2 + 1) { return i; } } return -1; } internal static int get_mono_channel(ChannelLayout layout, int stream_id, int prev) { for (int i = ((prev >= 0) ? (prev + 1) : 0); i < layout.nb_channels; i++) { if (layout.mapping[i] == stream_id + layout.nb_coupled_streams) { return i; } } return -1; } } internal static class Tables { internal static readonly float[] dct_table = new float[128] { 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.351851f, 0.33833f, 0.311806f, 0.2733f, 0.224292f, 0.166664f, 0.102631f, 0.034654f, -0.034654f, -0.102631f, -0.166664f, -0.224292f, -0.2733f, -0.311806f, -0.33833f, -0.351851f, 0.34676f, 0.293969f, 0.196424f, 0.068975f, -0.068975f, -0.196424f, -0.293969f, -0.34676f, -0.34676f, -0.293969f, -0.196424f, -0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.34676f, 0.33833f, 0.224292f, 0.034654f, -0.166664f, -0.311806f, -0.351851f, -0.2733f, -0.102631f, 0.102631f, 0.2733f, 0.351851f, 0.311806f, 0.166664f, -0.034654f, -0.224292f, -0.33833f, 0.326641f, 0.135299f, -0.135299f, -0.326641f, -0.326641f, -0.135299f, 0.135299f, 0.326641f, 0.326641f, 0.135299f, -0.135299f, -0.326641f, -0.326641f, -0.135299f, 0.135299f, 0.326641f, 0.311806f, 0.034654f, -0.2733f, -0.33833f, -0.102631f, 0.224292f, 0.351851f, 0.166664f, -0.166664f, -0.351851f, -0.224292f, 0.102631f, 0.33833f, 0.2733f, -0.034654f, -0.311806f, 0.293969f, -0.068975f, -0.34676f, -0.196424f, 0.196424f, 0.34676f, 0.068975f, -0.293969f, -0.293969f, 0.068975f, 0.34676f, 0.196424f, -0.196424f, -0.34676f, -0.068975f, 0.293969f, 0.2733f, -0.166664f, -0.33833f, 0.034654f, 0.351851f, 0.102631f, -0.311806f, -0.224292f, 0.224292f, 0.311806f, -0.102631f, -0.351851f, -0.034654f, 0.33833f, 0.166664f, -0.2733f }; internal static readonly float[] analysis_window = new float[240] { 4.3E-05f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f, 0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f, 0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.02059f, 0.02249f, 0.024472f, 0.026535f, 0.028679f, 0.030904f, 0.03321f, 0.035595f, 0.03806f, 0.040604f, 0.043227f, 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f, 0.070297f, 0.07368f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f, 0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.12408f, 0.128428f, 0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.1606f, 0.165435f, 0.170327f, 0.175276f, 0.18028f, 0.18534f, 0.190453f, 0.195619f, 0.200838f, 0.206107f, 0.211427f, 0.216797f, 0.222215f, 0.22768f, 0.233193f, 0.238751f, 0.244353f, 0.25f, 0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.29067f, 0.296632f, 0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.33928f, 0.345492f, 0.351729f, 0.357992f, 0.36428f, 0.37059f, 0.376923f, 0.383277f, 0.389651f, 0.396044f, 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f, 0.454249f, 0.46077f, 0.467298f, 0.473832f, 0.48037f, 0.486912f, 0.493455f, 0.5f, 0.506545f, 0.513088f, 0.51963f, 0.526168f, 0.532702f, 0.53923f, 0.545751f, 0.552264f, 0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f, 0.610349f, 0.616723f, 0.623077f, 0.62941f, 0.63572f, 0.642008f, 0.648271f, 0.654508f, 0.66072f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f, 0.70933f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.75f, 0.755647f, 0.761249f, 0.766807f, 0.77232f, 0.777785f, 0.783203f, 0.788573f, 0.793893f, 0.799162f, 0.804381f, 0.809547f, 0.81466f, 0.81972f, 0.824724f, 0.829673f, 0.834565f, 0.8394f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f, 0.87592f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f, 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.92632f, 0.929703f, 0.933013f, 0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f, 0.959396f, 0.96194f, 0.964405f, 0.96679f, 0.969096f, 0.971321f, 0.973465f, 0.975528f, 0.97751f, 0.97941f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f, 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f, 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1f }; internal static readonly int[] tbands = new int[19] { 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120 }; internal static readonly int[] extra_bands = new int[22] { 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200 }; internal static readonly float[] weights = new float[422] { -0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f, -0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f, -0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f, 0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f, 0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f, 24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f, -0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f, -0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f, -0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f, 1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f, 15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f, 0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f, -0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f, 0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f, 0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f, -1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f, -0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f, -0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f, 0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f, -0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f, 2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f, 0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f, -0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f, 0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f, 0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f, -4.60683f, 1.4697f, 325f / (356f * (float)Math.E), -1.81905f, -30.1699f, 5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f, -0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f, -0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f, -0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f, 1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f, -7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f, -0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f, 0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f, 0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f, -0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f, 10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f, -0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f, -0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f, -0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f, 0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f, -0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f, 0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f, 0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f, -0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f, 0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f, -0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f, -0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f, -0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f, -0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f, -0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f, 5.8427f, -0.38075f, 0.221894f, -1.41934f, -1879430f, 1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f, 0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f, -0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f, 0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f, -0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f, -975268f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f, 0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f, -0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f, -2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f, 0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f, -6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f, 0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f, -0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f, -0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f, 0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f, -0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f, 0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f, -0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f, 0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f, -2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f, 4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f, 0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f, -0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f, 0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f, 0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f, 3.95279f, 1.89068f, 0.486087f, -11.3343f, 3941600f, -0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f, 0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f, 0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f, 0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f, 4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f, -1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f, 3.87308f, 3.52558f }; internal static readonly int[] topo = new int[3] { 25, 15, 2 }; internal static readonly MLP net = new MLP { layers = 3, topo = topo, weights = weights }; internal static readonly float[] tansig_table = new float[201] { 0f, 0.039979f, 0.07983f, 0.119427f, 0.158649f, 0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f, 0.379949f, 0.413644f, 0.446244f, 0.4777f, 0.507977f, 0.53705f, 0.5649f, 0.591519f, 0.616909f, 0.641077f, 0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f, 0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.82104f, 0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, 0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.91542f, 0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f, 0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.96109f, 0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f, 0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f, 0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f, 0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.99202f, 0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f, 0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f, 0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.99759f, 0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f, 0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f, 0.999f, 0.999076f, 0.999147f, 0.999213f, 0.999273f, 0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f, 0.99955f, 0.999585f, 0.999617f, 0.999646f, 0.999673f, 0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f, 0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f, 0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, 0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f, 0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f, 0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.99997f, 0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.99998f, 0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f, 0.999988f, 0.999989f, 0.99999f, 0.99999f, 0.999991f, 0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f, 0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f, 0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f, 0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }; internal static readonly int[] mono_voice_bandwidth_thresholds = new int[8] { 11000, 1000, 14000, 1000, 17000, 1000, 21000, 2000 }; internal static readonly int[] mono_music_bandwidth_thresholds = new int[8] { 12000, 1000, 15000, 1000, 18000, 2000, 22000, 2000 }; internal static readonly int[] stereo_voice_bandwidth_thresholds = new int[8] { 11000, 1000, 14000, 1000, 21000, 2000, 28000, 2000 }; internal static readonly int[] stereo_music_bandwidth_thresholds = new int[8] { 12000, 1000, 18000, 2000, 21000, 2000, 30000, 2000 }; internal const int stereo_voice_threshold = 30000; internal const int stereo_music_threshold = 30000; internal static readonly int[][] mode_thresholds = new int[2][] { new int[2] { 64000, 16000 }, new int[2] { 36000, 16000 } }; } internal static class ResamplerFactory { public static IResampler CreateResampler(int numChannels, int inRate, int outRate, int quality, TextWriter logger = null) { return CreateResampler(numChannels, inRate, outRate, inRate, outRate, quality, logger); } public static IResampler CreateResampler(int numChannels, int ratioNum, int ratioDen, int inRate, int outRate, int quality, TextWriter logger = null) { if (numChannels <= 0) { throw new ArgumentOutOfRangeException("numChannels"); } if (ratioNum <= 0) { throw new ArgumentOutOfRangeException("ratioNum"); } if (ratioDen <= 0) { throw new ArgumentOutOfRangeException("ratioDen"); } if (inRate <= 0) { throw new ArgumentOutOfRangeException("inRate"); } if (outRate <= 0) { throw new ArgumentOutOfRangeException("outRate"); } if (quality < 0 || quality > 10) { throw new ArgumentOutOfRangeException("quality", "Quality must be between 0 and 10"); } return new SpeexResampler(numChannels, ratioNum, ratioDen, inRate, outRate, quality); } } } namespace Concentus.Silk { internal static class ApplySineWindow { private static readonly short[] freq_table_Q16 = new short[27] { 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702 }; internal static void silk_apply_sine_window(short[] px_win, int px_win_ptr, short[] px, int px_ptr, int win_type, int length) { int num = (length >> 2) - 4; int num2 = freq_table_Q16[num]; int num3 = Inlines.silk_SMULWB(num2, -num2); int num4; int num5; if (win_type == 1) { num4 = 0; num5 = num2 + Inlines.silk_RSHIFT(length, 3); } else { num4 = 65536; num5 = 65536 + Inlines.silk_RSHIFT(num3, 1) + Inlines.silk_RSHIFT(length, 4); } for (num = 0; num < length; num += 4) { int num6 = px_win_ptr + num; int num7 = px_ptr + num; px_win[num6] = (short)Inlines.silk_SMULWB(Inlines.silk_RSHIFT(num4 + num5, 1), px[num7]); px_win[num6 + 1] = (short)Inlines.silk_SMULWB(num5, px[num7 + 1]); num4 = Inlines.silk_SMULWB(num5, num3) + Inlines.silk_LSHIFT(num5, 1) - num4 + 1; num4 = Inlines.silk_min(num4, 65536); px_win[num6 + 2] = (short)Inlines.silk_SMULWB(Inlines.silk_RSHIFT(num4 + num5, 1), px[num7 + 2]); px_win[num6 + 3] = (short)Inlines.silk_SMULWB(num4, px[num7 + 3]); num5 = Inlines.silk_SMULWB(num4, num3) + Inlines.silk_LSHIFT(num4, 1) - num5; num5 = Inlines.silk_min(num5, 65536); } } } internal static class BurgModified { private const int MAX_FRAME_SIZE = 384; private const int QA = 25; private const int N_BITS_HEAD_ROOM = 2; private const int MIN_RSHIFTS = -16; private const int MAX_RSHIFTS = 7; internal static void silk_burg_modified(BoxedValueInt res_nrg, BoxedValueInt res_nrg_Q, int[] A_Q16, short[] x, int x_ptr, int minInvGain_Q30, int subfr_length, int nb_subfr, int D) { int[] array = new int[16]; int[] array2 = new int[16]; int[] array3 = new int[16]; int[] array4 = new int[17]; int[] array5 = new int[17]; int[] array6 = new int[16]; long num = Inlines.silk_inner_prod16_aligned_64(x, x_ptr, x, x_ptr, subfr_length * nb_subfr); int num2 = Inlines.silk_CLZ64(num); int num3 = 35 - num2; if (num3 > 7) { num3 = 7; } if (num3 < -16) { num3 = -16; } int num4 = (int)((num3 <= 0) ? Inlines.silk_LSHIFT32((int)num, -num3) : Inlines.silk_RSHIFT64(num, num3)); array5[0] = (array4[0] = num4 + Inlines.silk_SMMUL(42950, num4) + 1); Arrays.MemSetInt(array, 0, 16); if (num3 > 0) { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; for (int j = 1; j < D + 1; j++) { array[j - 1] += (int)Inlines.silk_RSHIFT64(Inlines.silk_inner_prod16_aligned_64(x, num5, x, num5 + j, subfr_length - j), num3); } } } else { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; CeltPitchXCorr.pitch_xcorr(x, num5, x, num5 + 1, array6, subfr_length - D, D); for (int j = 1; j < D + 1; j++) { int k = j + subfr_length - D; int num6 = 0; for (; k < subfr_length; k++) { num6 = Inlines.MAC16_16(num6, x[num5 + k], x[num5 + k - j]); } array6[j - 1] += num6; } for (int j = 1; j < D + 1; j++) { array[j - 1] += Inlines.silk_LSHIFT32(array6[j - 1], -num3); } } } Arrays.MemCopy(array, 0, array2, 0, 16); array5[0] = (array4[0] = num4 + Inlines.silk_SMMUL(42950, num4) + 1); int num7 = 1073741824; int num8 = 0; for (int j = 0; j < D; j++) { int num9; int num10; if (num3 > -2) { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; int b = -Inlines.silk_LSHIFT32(x[num5 + j], 16 - num3); int b2 = -Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 16 - num3); num9 = Inlines.silk_LSHIFT32(x[num5 + j], 9); num10 = Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 9); for (int l = 0; l < j; l++) { array[l] = Inlines.silk_SMLAWB(array[l], b, x[num5 + j - l - 1]); array2[l] = Inlines.silk_SMLAWB(array2[l], b2, x[num5 + subfr_length - j + l]); int b3 = array3[l]; num9 = Inlines.silk_SMLAWB(num9, b3, x[num5 + j - l - 1]); num10 = Inlines.silk_SMLAWB(num10, b3, x[num5 + subfr_length - j + l]); } num9 = Inlines.silk_LSHIFT32(-num9, 7 - num3); num10 = Inlines.silk_LSHIFT32(-num10, 7 - num3); for (int l = 0; l <= j; l++) { array4[l] = Inlines.silk_SMLAWB(array4[l], num9, x[num5 + j - l]); array5[l] = Inlines.silk_SMLAWB(array5[l], num10, x[num5 + subfr_length - j + l - 1]); } } } else { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; int b = -Inlines.silk_LSHIFT32(x[num5 + j], -num3); int b2 = -Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], -num3); num9 = Inlines.silk_LSHIFT32(x[num5 + j], 17); num10 = Inlines.silk_LSHIFT32(x[num5 + subfr_length - j - 1], 17); for (int l = 0; l < j; l++) { array[l] = Inlines.silk_MLA(array[l], b, x[num5 + j - l - 1]); array2[l] = Inlines.silk_MLA(array2[l], b2, x[num5 + subfr_length - j + l]); int c = Inlines.silk_RSHIFT_ROUND(array3[l], 8); num9 = Inlines.silk_MLA(num9, x[num5 + j - l - 1], c); num10 = Inlines.silk_MLA(num10, x[num5 + subfr_length - j + l], c); } num9 = -num9; num10 = -num10; for (int l = 0; l <= j; l++) { array4[l] = Inlines.silk_SMLAWW(array4[l], num9, Inlines.silk_LSHIFT32(x[num5 + j - l], -num3 - 1)); array5[l] = Inlines.silk_SMLAWW(array5[l], num10, Inlines.silk_LSHIFT32(x[num5 + subfr_length - j + l - 1], -num3 - 1)); } } } num9 = array[j]; num10 = array2[j]; int a = 0; int num11 = Inlines.silk_ADD32(array5[0], array4[0]); for (int l = 0; l < j; l++) { int b3 = array3[l]; num2 = Inlines.silk_CLZ32(Inlines.silk_abs(b3)) - 1; num2 = Inlines.silk_min(7, num2); int c = Inlines.silk_LSHIFT32(b3, num2); num9 = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(array2[j - l - 1], c), 7 - num2); num10 = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(array[j - l - 1], c), 7 - num2); a = Inlines.silk_ADD_LSHIFT32(a, Inlines.silk_SMMUL(array5[j - l], c), 7 - num2); num11 = Inlines.silk_ADD_LSHIFT32(num11, Inlines.silk_SMMUL(Inlines.silk_ADD32(array5[l + 1], array4[l + 1]), c), 7 - num2); } array4[j + 1] = num9; array5[j + 1] = num10; a = Inlines.silk_ADD32(a, num10); a = Inlines.silk_LSHIFT32(-a, 1); int num12 = ((Inlines.silk_abs(a) >= num11) ? ((a > 0) ? int.MaxValue : int.MinValue) : Inlines.silk_DIV32_varQ(a, num11, 31)); num9 = 1073741824 - Inlines.silk_SMMUL(num12, num12); num9 = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(num7, num9), 2); if (num9 <= minInvGain_Q30) { num10 = 1073741824 - Inlines.silk_DIV32_varQ(minInvGain_Q30, num7, 30); num12 = Inlines.silk_SQRT_APPROX(num10); num12 = Inlines.silk_RSHIFT32(num12 + Inlines.silk_DIV32(num10, num12), 1); num12 = Inlines.silk_LSHIFT32(num12, 16); if (a < 0) { num12 = -num12; } num7 = minInvGain_Q30; num8 = 1; } else { num7 = num9; } for (int l = 0; l < j + 1 >> 1; l++) { num9 = array3[l]; num10 = array3[j - l - 1]; array3[l] = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(num10, num12), 1); array3[j - l - 1] = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(num9, num12), 1); } array3[j] = Inlines.silk_RSHIFT32(num12, 6); if (num8 != 0) { for (int l = j + 1; l < D; l++) { array3[l] = 0; } break; } for (int l = 0; l <= j + 1; l++) { num9 = array4[l]; num10 = array5[j - l + 1]; array4[l] = Inlines.silk_ADD_LSHIFT32(num9, Inlines.silk_SMMUL(num10, num12), 1); array5[j - l + 1] = Inlines.silk_ADD_LSHIFT32(num10, Inlines.silk_SMMUL(num9, num12), 1); } } if (num8 != 0) { for (int l = 0; l < D; l++) { A_Q16[l] = -Inlines.silk_RSHIFT_ROUND(array3[l], 9); } if (num3 > 0) { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; num4 -= (int)Inlines.silk_RSHIFT64(Inlines.silk_inner_prod16_aligned_64(x, num5, x, num5, D), num3); } } else { for (int i = 0; i < nb_subfr; i++) { int num5 = x_ptr + i * subfr_length; num4 -= Inlines.silk_LSHIFT32(Inlines.silk_inner_prod_self(x, num5, D), -num3); } } res_nrg.Val = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(num7, num4), 2); res_nrg_Q.Val = -num3; } else { int num11 = array4[0]; int num9 = 65536; for (int l = 0; l < D; l++) { int c = Inlines.silk_RSHIFT_ROUND(array3[l], 9); num11 = Inlines.silk_SMLAWW(num11, array4[l + 1], c); num9 = Inlines.silk_SMLAWW(num9, c, c); A_Q16[l] = -c; } res_nrg.Val = Inlines.silk_SMLAWW(num11, Inlines.silk_SMMUL(42950, num4), -num9); res_nrg_Q.Val = -num3; } } } internal static class BWExpander { internal static void silk_bwexpander_32(int[] ar, int d, int chirp_Q16) { int b = chirp_Q16 - 65536; for (int i = 0; i < d - 1; i++) { ar[i] = Inlines.silk_SMULWW(chirp_Q16, ar[i]); chirp_Q16 += Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, b), 16); } ar[d - 1] = Inlines.silk_SMULWW(chirp_Q16, ar[d - 1]); } internal static void silk_bwexpander(short[] ar, int d, int chirp_Q16) { int b = chirp_Q16 - 65536; for (int i = 0; i < d - 1; i++) { ar[i] = (short)Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, ar[i]), 16); chirp_Q16 += Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, b), 16); } ar[d - 1] = (short)Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, ar[d - 1]), 16); } } internal static class CNG { internal static void silk_CNG_exc(Span exc_Q10, int exc_Q10_ptr, int[] exc_buf_Q14, int Gain_Q16, int length, ref int rand_seed) { int num; for (num = 255; num > length; num = Inlines.silk_RSHIFT(num, 1)) { } int num2 = rand_seed; for (int i = exc_Q10_ptr; i < exc_Q10_ptr + length; i++) { num2 = Inlines.silk_RAND(num2); int num3 = Inlines.silk_RSHIFT(num2, 24) & num; exc_Q10[i] = (short)Inlines.silk_SAT16(Inlines.silk_SMULWW(exc_buf_Q14[num3], Gain_Q16 >> 4)); } rand_seed = num2; } internal static void silk_CNG_Reset(SilkChannelDecoder psDec) { int num = Inlines.silk_DIV32_16(32767, (short)(psDec.LPC_order + 1)); int num2 = 0; for (int i = 0; i < psDec.LPC_order; i++) { num2 += num; psDec.sCNG.CNG_smth_NLSF_Q15[i] = (short)num2; } psDec.sCNG.CNG_smth_Gain_Q16 = 0; psDec.sCNG.rand_seed = 3176576; } internal static void silk_CNG(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span frame, int frame_ptr, int length) { short[] array = new short[psDec.LPC_order]; CNGState sCNG = psDec.sCNG; if (psDec.fs_kHz != sCNG.fs_kHz) { silk_CNG_Reset(psDec); sCNG.fs_kHz = psDec.fs_kHz; } if (psDec.lossCnt == 0 && psDec.prevSignalType == 0) { for (int i = 0; i < psDec.LPC_order; i++) { sCNG.CNG_smth_NLSF_Q15[i] += (short)Inlines.silk_SMULWB(psDec.prevNLSF_Q15[i] - sCNG.CNG_smth_NLSF_Q15[i], 16348); } int num = 0; for (int i = 0; i < psDec.nb_subfr; i++) { if (psDecCtrl.Gains_Q16[i] > num) { num = psDecCtrl.Gains_Q16[i]; } } Arrays.MemMoveInt(sCNG.CNG_exc_buf_Q14, 0, psDec.subfr_length, (psDec.nb_subfr - 1) * psDec.subfr_length); for (int i = 0; i < psDec.nb_subfr; i++) { sCNG.CNG_smth_Gain_Q16 += Inlines.silk_SMULWB(psDecCtrl.Gains_Q16[i] - sCNG.CNG_smth_Gain_Q16, 4634); } } if (psDec.lossCnt != 0) { int[] array2 = new int[length + 16]; int num2 = Inlines.silk_SMULWW(psDec.sPLC.randScale_Q14, psDec.sPLC.prevGain_Q16[1]); if (num2 >= 2097152 || sCNG.CNG_smth_Gain_Q16 > 8388608) { num2 = Inlines.silk_SMULTT(num2, num2); num2 = Inlines.silk_SUB_LSHIFT32(Inlines.silk_SMULTT(sCNG.CNG_smth_Gain_Q16, sCNG.CNG_smth_Gain_Q16), num2, 5); num2 = Inlines.silk_LSHIFT32(Inlines.silk_SQRT_APPROX(num2), 16); } else { num2 = Inlines.silk_SMULWW(num2, num2); num2 = Inlines.silk_SUB_LSHIFT32(Inlines.silk_SMULWW(sCNG.CNG_smth_Gain_Q16, sCNG.CNG_smth_Gain_Q16), num2, 5); num2 = Inlines.silk_LSHIFT32(Inlines.silk_SQRT_APPROX(num2), 8); } silk_CNG_exc(array2, 16, sCNG.CNG_exc_buf_Q14, num2, length, ref sCNG.rand_seed); NLSF.silk_NLSF2A(array, sCNG.CNG_smth_NLSF_Q15, psDec.LPC_order); Arrays.MemCopy(sCNG.CNG_synth_state, 0, array2, 0, 16); for (int i = 0; i < length; i++) { int num3 = 16 + i; int a = Inlines.silk_RSHIFT(psDec.LPC_order, 1); a = Inlines.silk_SMLAWB(a, array2[num3 - 1], array[0]); a = Inlines.silk_SMLAWB(a, array2[num3 - 2], array[1]); a = Inlines.silk_SMLAWB(a, array2[num3 - 3], array[2]); a = Inlines.silk_SMLAWB(a, array2[num3 - 4], array[3]); a = Inlines.silk_SMLAWB(a, array2[num3 - 5], array[4]); a = Inlines.silk_SMLAWB(a, array2[num3 - 6], array[5]); a = Inlines.silk_SMLAWB(a, array2[num3 - 7], array[6]); a = Inlines.silk_SMLAWB(a, array2[num3 - 8], array[7]); a = Inlines.silk_SMLAWB(a, array2[num3 - 9], array[8]); a = Inlines.silk_SMLAWB(a, array2[num3 - 10], array[9]); if (psDec.LPC_order == 16) { a = Inlines.silk_SMLAWB(a, array2[num3 - 11], array[10]); a = Inlines.silk_SMLAWB(a, array2[num3 - 12], array[11]); a = Inlines.silk_SMLAWB(a, array2[num3 - 13], array[12]); a = Inlines.silk_SMLAWB(a, array2[num3 - 14], array[13]); a = Inlines.silk_SMLAWB(a, array2[num3 - 15], array[14]); a = Inlines.silk_SMLAWB(a, array2[num3 - 16], array[15]); } array2[num3] = Inlines.silk_ADD_LSHIFT(array2[num3], a, 4); frame[frame_ptr + i] = Inlines.silk_ADD_SAT16(frame[frame_ptr + i], (short)Inlines.silk_RSHIFT_ROUND(array2[num3], 10)); } Arrays.MemCopy(array2, length, sCNG.CNG_synth_state, 0, 16); } else { Arrays.MemSetInt(sCNG.CNG_synth_state, 0, psDec.LPC_order); } } } internal static class CodeSigns { private static int silk_enc_map(int a) { return Inlines.silk_RSHIFT(a, 15) + 1; } private static int silk_dec_map(int a) { return Inlines.silk_LSHIFT(a, 1) - 1; } internal static void silk_encode_signs(EntropyCoder psRangeEnc, Span encodedData, Span pulses, int length, int signalType, int quantOffsetType, int[] sum_pulses) { byte[] array = new byte[2]; byte[] silk_sign_iCDF = Tables.silk_sign_iCDF; array[1] = 0; int num = 0; int num2 = Inlines.silk_SMULBB(7, Inlines.silk_ADD_LSHIFT(quantOffsetType, signalType, 1)); int num3 = num2; length = Inlines.silk_RSHIFT(length + 8, 4); for (num2 = 0; num2 < length; num2++) { int num4 = sum_pulses[num2]; if (num4 > 0) { array[0] = silk_sign_iCDF[num3 + Inlines.silk_min(num4 & 0x1F, 6)]; for (int i = num; i < num + 16; i++) { if (pulses[i] != 0) { psRangeEnc.enc_icdf(encodedData, silk_enc_map(pulses[i]), array, 8u); } } } num += 16; } } internal static void silk_decode_signs(EntropyCoder psRangeDec, ReadOnlySpan encodedData, short[] pulses, int length, int signalType, int quantOffsetType, int[] sum_pulses) { byte[] array = new byte[2]; byte[] silk_sign_iCDF = Tables.silk_sign_iCDF; array[1] = 0; int num = 0; int num2 = Inlines.silk_SMULBB(7, Inlines.silk_ADD_LSHIFT(quantOffsetType, signalType, 1)); int num3 = num2; length = Inlines.silk_RSHIFT(length + 8, 4); for (num2 = 0; num2 < length; num2++) { int num4 = sum_pulses[num2]; if (num4 > 0) { array[0] = silk_sign_iCDF[num3 + Inlines.silk_min(num4 & 0x1F, 6)]; for (int i = 0; i < 16; i++) { if (pulses[num + i] > 0) { pulses[num + i] *= (short)silk_dec_map(psRangeDec.dec_icdf(encodedData, array, 8u)); } } } num += 16; } } } internal static class CorrelateMatrix { internal static void silk_corrVector(short[] x, int x_ptr, short[] t, int t_ptr, int L, int order, int[] Xt, int rshifts) { int num = x_ptr + order - 1; if (rshifts > 0) { for (int i = 0; i < order; i++) { int num2 = 0; for (int j = 0; j < L; j++) { num2 += Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num + j], t[t_ptr + j]), rshifts); } Xt[i] = num2; num--; } } else { for (int i = 0; i < order; i++) { Xt[i] = Inlines.silk_inner_prod(x, num, t, t_ptr, L); num--; } } } internal static void silk_corrMatrix(short[] x, int x_ptr, int L, int order, int head_room, int[] XX, int XX_ptr, BoxedValueInt rshifts) { SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, x, x_ptr, L + order - 1); int num = Inlines.silk_max(head_room - Inlines.silk_CLZ32(energy), 0); energy = Inlines.silk_RSHIFT32(energy, num); shift += num; for (int i = x_ptr; i < x_ptr + order - 1; i++) { energy -= Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[i], x[i]), shift); } if (shift < rshifts.Val) { energy = Inlines.silk_RSHIFT32(energy, rshifts.Val - shift); shift = rshifts.Val; } Inlines.MatrixSet(XX, XX_ptr, 0, 0, order, energy); int num2 = x_ptr + order - 1; for (int j = 1; j < order; j++) { energy = Inlines.silk_SUB32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + L - j], x[num2 + L - j]), shift)); energy = Inlines.silk_ADD32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 - j], x[num2 - j]), shift)); Inlines.MatrixSet(XX, XX_ptr, j, j, order, energy); } int num3 = x_ptr + order - 2; if (shift > 0) { for (int k = 1; k < order; k++) { energy = 0; for (int i = 0; i < L; i++) { energy += Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + i], x[num3 + i]), shift); } Inlines.MatrixSet(XX, XX_ptr, k, 0, order, energy); Inlines.MatrixSet(XX, XX_ptr, 0, k, order, energy); for (int j = 1; j < order - k; j++) { energy = Inlines.silk_SUB32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 + L - j], x[num3 + L - j]), shift)); energy = Inlines.silk_ADD32(energy, Inlines.silk_RSHIFT32(Inlines.silk_SMULBB(x[num2 - j], x[num3 - j]), shift)); Inlines.MatrixSet(XX, XX_ptr, k + j, j, order, energy); Inlines.MatrixSet(XX, XX_ptr, j, k + j, order, energy); } num3--; } } else { for (int k = 1; k < order; k++) { energy = Inlines.silk_inner_prod(x, num2, x, num3, L); Inlines.MatrixSet(XX, XX_ptr, k, 0, order, energy); Inlines.MatrixSet(XX, XX_ptr, 0, k, order, energy); for (int j = 1; j < order - k; j++) { energy = Inlines.silk_SUB32(energy, Inlines.silk_SMULBB(x[num2 + L - j], x[num3 + L - j])); energy = Inlines.silk_SMLABB(energy, x[num2 - j], x[num3 - j]); Inlines.MatrixSet(XX, XX_ptr, k + j, j, order, energy); Inlines.MatrixSet(XX, XX_ptr, j, k + j, order, energy); } num3--; } } rshifts.Val = shift; } } internal static class DecodeAPI { internal static int silk_InitDecoder(SilkDecoder decState) { decState.Reset(); int result = SilkError.SILK_NO_ERROR; SilkChannelDecoder[] channel_state = decState.channel_state; for (int i = 0; i < 2; i++) { result = channel_state[i].silk_init_decoder(); } decState.sStereo.Reset(); decState.prev_decode_only_middle = 0; return result; } internal static int silk_Decode(SilkDecoder psDec, DecControlState decControl, ReadOnlySpan frameData, int lostFlag, int newPacketFlag, EntropyCoder psRangeDec, Span samplesOut, int samplesOut_ptr, out int nSamplesOut) { int num = 0; int num2 = SilkError.SILK_NO_ERROR; BoxedValueInt boxedValueInt = new BoxedValueInt(); int[] array = new int[2]; int[] array2 = new int[2]; SilkChannelDecoder[] channel_state = psDec.channel_state; nSamplesOut = 0; if (newPacketFlag != 0) { for (int i = 0; i < decControl.nChannelsInternal; i++) { channel_state[i].nFramesDecoded = 0; } } if (decControl.nChannelsInternal > psDec.nChannelsInternal) { num2 += channel_state[1].silk_init_decoder(); } int num3 = ((decControl.nChannelsInternal == 1 && psDec.nChannelsInternal == 2 && decControl.internalSampleRate == 1000 * channel_state[0].fs_kHz) ? 1 : 0); if (channel_state[0].nFramesDecoded == 0) { for (int i = 0; i < decControl.nChannelsInternal; i++) { if (decControl.payloadSize_ms == 0) { channel_state[i].nFramesPerPacket = 1; channel_state[i].nb_subfr = 2; } else if (decControl.payloadSize_ms == 10) { channel_state[i].nFramesPerPacket = 1; channel_state[i].nb_subfr = 2; } else if (decControl.payloadSize_ms == 20) { channel_state[i].nFramesPerPacket = 1; channel_state[i].nb_subfr = 4; } else if (decControl.payloadSize_ms == 40) { channel_state[i].nFramesPerPacket = 2; channel_state[i].nb_subfr = 4; } else { if (decControl.payloadSize_ms != 60) { return SilkError.SILK_DEC_INVALID_FRAME_SIZE; } channel_state[i].nFramesPerPacket = 3; channel_state[i].nb_subfr = 4; } int num4 = (decControl.internalSampleRate >> 10) + 1; if (num4 != 8 && num4 != 12 && num4 != 16) { return SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY; } num2 += channel_state[i].silk_decoder_set_fs(num4, decControl.API_sampleRate); } } if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2 && (psDec.nChannelsAPI == 1 || psDec.nChannelsInternal == 1)) { Arrays.MemSetShort(psDec.sStereo.pred_prev_Q13, 0, 2); Arrays.MemSetShort(psDec.sStereo.sSide, 0, 2); channel_state[1].resampler_state.Assign(channel_state[0].resampler_state); } psDec.nChannelsAPI = decControl.nChannelsAPI; psDec.nChannelsInternal = decControl.nChannelsInternal; if (decControl.API_sampleRate > 48000 || decControl.API_sampleRate < 8000) { return SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY; } if (lostFlag != 1 && channel_state[0].nFramesDecoded == 0) { for (int i = 0; i < decControl.nChannelsInternal; i++) { for (int j = 0; j < channel_state[i].nFramesPerPacket; j++) { channel_state[i].VAD_flags[j] = psRangeDec.dec_bit_logp(frameData, 1u); } channel_state[i].LBRR_flag = psRangeDec.dec_bit_logp(frameData, 1u); } for (int i = 0; i < decControl.nChannelsInternal; i++) { Arrays.MemSetInt(channel_state[i].LBRR_flags, 0, 3); if (channel_state[i].LBRR_flag == 0) { continue; } if (channel_state[i].nFramesPerPacket == 1) { channel_state[i].LBRR_flags[0] = 1; continue; } int a = psRangeDec.dec_icdf(frameData, Tables.silk_LBRR_flags_iCDF_ptr[channel_state[i].nFramesPerPacket - 2], 8u) + 1; for (int j = 0; j < channel_state[i].nFramesPerPacket; j++) { channel_state[i].LBRR_flags[j] = Inlines.silk_RSHIFT(a, j) & 1; } } if (lostFlag == 0) { for (int j = 0; j < channel_state[0].nFramesPerPacket; j++) { for (int i = 0; i < decControl.nChannelsInternal; i++) { if (channel_state[i].LBRR_flags[j] == 0) { continue; } short[] pulses = new short[320]; if (decControl.nChannelsInternal == 2 && i == 0) { Stereo.silk_stereo_decode_pred(psRangeDec, frameData, array2); if (channel_state[1].LBRR_flags[j] == 0) { BoxedValueInt boxedValueInt2 = new BoxedValueInt(num); Stereo.silk_stereo_decode_mid_only(psRangeDec, frameData, boxedValueInt2); num = boxedValueInt2.Val; } } DecodeIndices.silk_decode_indices(condCoding: (j > 0 && channel_state[i].LBRR_flags[j - 1] != 0) ? 2 : 0, psDec: channel_state[i], psRangeDec: psRangeDec, frameData: frameData, FrameIndex: j, decode_LBRR: 1); DecodePulses.silk_decode_pulses(psRangeDec, frameData, pulses, channel_state[i].indices.signalType, channel_state[i].indices.quantOffsetType, channel_state[i].frame_length); } } } } if (decControl.nChannelsInternal == 2) { if (lostFlag == 0 || (lostFlag == 2 && channel_state[0].LBRR_flags[channel_state[0].nFramesDecoded] == 1)) { Stereo.silk_stereo_decode_pred(psRangeDec, frameData, array2); if ((lostFlag == 0 && channel_state[1].VAD_flags[channel_state[0].nFramesDecoded] == 0) || (lostFlag == 2 && channel_state[1].LBRR_flags[channel_state[0].nFramesDecoded] == 0)) { BoxedValueInt boxedValueInt3 = new BoxedValueInt(num); Stereo.silk_stereo_decode_mid_only(psRangeDec, frameData, boxedValueInt3); num = boxedValueInt3.Val; } else { num = 0; } } else { for (int i = 0; i < 2; i++) { array2[i] = psDec.sStereo.pred_prev_Q13[i]; } } } if (decControl.nChannelsInternal == 2 && num == 0 && psDec.prev_decode_only_middle == 1) { Arrays.MemSetShort(psDec.channel_state[1].outBuf, 0, 480); Arrays.MemSetInt(psDec.channel_state[1].sLPC_Q14_buf, 0, 16); psDec.channel_state[1].lagPrev = 100; psDec.channel_state[1].LastGainIndex = 10; psDec.channel_state[1].prevSignalType = 0; psDec.channel_state[1].first_frame_after_reset = 1; } int num5 = ((decControl.internalSampleRate * decControl.nChannelsInternal < decControl.API_sampleRate * decControl.nChannelsAPI) ? 1 : 0); Span span; if (num5 != 0) { span = samplesOut; array[0] = samplesOut_ptr; array[1] = samplesOut_ptr + channel_state[0].frame_length + 2; } else { span = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)]; array[0] = 0; array[1] = channel_state[0].frame_length + 2; } int num6 = ((lostFlag != 0) ? ((psDec.prev_decode_only_middle == 0 || (decControl.nChannelsInternal == 2 && lostFlag == 2 && channel_state[1].LBRR_flags[channel_state[1].nFramesDecoded] == 1)) ? 1 : 0) : ((num == 0) ? 1 : 0)); for (int i = 0; i < decControl.nChannelsInternal; i++) { if (i == 0 || num6 != 0) { int num7 = channel_state[0].nFramesDecoded - i; int condCoding = ((num7 > 0) ? ((lostFlag == 2) ? ((channel_state[i].LBRR_flags[num7 - 1] != 0) ? 2 : 0) : ((i > 0 && psDec.prev_decode_only_middle != 0) ? 1 : 2)) : 0); num2 += channel_state[i].silk_decode_frame(psRangeDec, frameData, span, array[i] + 2, boxedValueInt, lostFlag, condCoding); } else { Arrays.MemSetWithOffset(span, 0, array[i] + 2, boxedValueInt.Val); } channel_state[i].nFramesDecoded++; } if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2) { Stereo.silk_stereo_MS_to_LR(psDec.sStereo, span, array[0], span, array[1], array2, channel_state[0].fs_kHz, boxedValueInt.Val); } else { MemoryExtensions.AsSpan(psDec.sStereo.sMid, 0, 2).CopyTo(span.Slice(array[0])); span.Slice(array[0] + boxedValueInt.Val, 2).CopyTo(psDec.sStereo.sMid); } nSamplesOut = Inlines.silk_DIV32(boxedValueInt.Val * decControl.API_sampleRate, Inlines.silk_SMULBB(channel_state[0].fs_kHz, 1000)); Span output; int num8; if (decControl.nChannelsAPI == 2) { output = new short[nSamplesOut]; num8 = 0; } else { output = samplesOut; num8 = samplesOut_ptr; } if (num5 != 0) { short[] array3 = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)]; samplesOut.Slice(samplesOut_ptr, decControl.nChannelsInternal * (channel_state[0].frame_length + 2)).CopyTo(array3); span = array3; array[0] = 0; array[1] = channel_state[0].frame_length + 2; } for (int i = 0; i < Inlines.silk_min(decControl.nChannelsAPI, decControl.nChannelsInternal); i++) { num2 += Resampler.silk_resampler(channel_state[i].resampler_state, output, num8, span, array[i] + 1, boxedValueInt.Val); if (decControl.nChannelsAPI == 2) { int num9 = samplesOut_ptr + i; for (int j = 0; j < nSamplesOut; j++) { samplesOut[num9 + 2 * j] = output[num8 + j]; } } } if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 1) { if (num3 != 0) { num2 += Resampler.silk_resampler(channel_state[1].resampler_state, output, num8, span, array[0] + 1, boxedValueInt.Val); for (int j = 0; j < nSamplesOut; j++) { samplesOut[samplesOut_ptr + 1 + 2 * j] = output[num8 + j]; } } else { for (int j = 0; j < nSamplesOut; j++) { samplesOut[samplesOut_ptr + 1 + 2 * j] = samplesOut[samplesOut_ptr + 2 * j]; } } } if (channel_state[0].prevSignalType == 2) { int[] array4 = new int[3] { 6, 4, 3 }; decControl.prevPitchLag = channel_state[0].lagPrev * array4[channel_state[0].fs_kHz - 8 >> 2]; } else { decControl.prevPitchLag = 0; } if (lostFlag == 1) { for (int j = 0; j < psDec.nChannelsInternal; j++) { psDec.channel_state[j].LastGainIndex = 10; } } else { psDec.prev_decode_only_middle = num; } return num2; } } internal static class DecodeCore { internal static void silk_decode_core(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span xq, int xq_ptr, short[] pulses) { int num = 0; short[] lTPCoef_Q = psDecCtrl.LTPCoef_Q14; short[] array = new short[psDec.ltp_mem_length]; int[] array2 = new int[psDec.ltp_mem_length + psDec.frame_length]; int[] array3 = new int[psDec.subfr_length]; int[] array4 = new int[psDec.subfr_length + 16]; int num2 = Tables.silk_Quantization_Offsets_Q10[psDec.indices.signalType >> 1][psDec.indices.quantOffsetType]; int num3 = ((psDec.indices.NLSFInterpCoef_Q2 < 4) ? 1 : 0); int seed = psDec.indices.Seed; for (int i = 0; i < psDec.frame_length; i++) { seed = Inlines.silk_RAND(seed); psDec.exc_Q14[i] = Inlines.silk_LSHIFT(pulses[i], 14); if (psDec.exc_Q14[i] > 0) { psDec.exc_Q14[i] -= 1280; } else if (psDec.exc_Q14[i] < 0) { psDec.exc_Q14[i] += 1280; } psDec.exc_Q14[i] += num2 << 4; if (seed < 0) { psDec.exc_Q14[i] = -psDec.exc_Q14[i]; } seed = Inlines.silk_ADD32_ovflw(seed, pulses[i]); } Arrays.MemCopy(psDec.sLPC_Q14_buf, 0, array4, 0, 16); int num4 = 0; int num5 = xq_ptr; int num6 = psDec.ltp_mem_length; for (int j = 0; j < psDec.nb_subfr; j++) { int[] array5 = array3; int num7 = 0; short[] array6 = psDecCtrl.PredCoef_Q12[j >> 1]; int num8 = j * 5; int num9 = psDec.indices.signalType; int b = Inlines.silk_RSHIFT(psDecCtrl.Gains_Q16[j], 6); int a = Inlines.silk_INVERSE32_varQ(psDecCtrl.Gains_Q16[j], 47); int num10; if (psDecCtrl.Gains_Q16[j] != psDec.prev_gain_Q16) { num10 = Inlines.silk_DIV32_varQ(psDec.prev_gain_Q16, psDecCtrl.Gains_Q16[j], 16); for (int i = 0; i < 16; i++) { array4[i] = Inlines.silk_SMULWW(num10, array4[i]); } } else { num10 = 65536; } psDec.prev_gain_Q16 = psDecCtrl.Gains_Q16[j]; if (psDec.lossCnt != 0 && psDec.prevSignalType == 2 && psDec.indices.signalType != 2 && j < 2) { Arrays.MemSetWithOffset(lTPCoef_Q, (short)0, num8, 5); lTPCoef_Q[num8 + 2] = 4096; num9 = 2; psDecCtrl.pitchL[j] = psDec.lagPrev; } if (num9 == 2) { num = psDecCtrl.pitchL[j]; if (j == 0 || (j == 2 && num3 != 0)) { int num11 = psDec.ltp_mem_length - num - psDec.LPC_order - 2; if (j == 2) { xq.Slice(xq_ptr, 2 * psDec.subfr_length).CopyTo(MemoryExtensions.AsSpan(psDec.outBuf, psDec.ltp_mem_length)); } Filters.silk_LPC_analysis_filter(array, num11, psDec.outBuf, num11 + j * psDec.subfr_length, array6, 0, psDec.ltp_mem_length - num11, psDec.LPC_order); if (j == 0) { a = Inlines.silk_LSHIFT(Inlines.silk_SMULWB(a, psDecCtrl.LTP_scale_Q14), 2); } for (int i = 0; i < num + 2; i++) { array2[num6 - i - 1] = Inlines.silk_SMULWB(a, array[psDec.ltp_mem_length - i - 1]); } } else if (num10 != 65536) { for (int i = 0; i < num + 2; i++) { array2[num6 - i - 1] = Inlines.silk_SMULWW(num10, array2[num6 - i - 1]); } } } if (num9 == 2) { int num12 = num6 - num + 2; for (int i = 0; i < psDec.subfr_length; i++) { int a2 = 2; a2 = Inlines.silk_SMLAWB(a2, array2[num12], lTPCoef_Q[num8]); a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 1], lTPCoef_Q[num8 + 1]); a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 2], lTPCoef_Q[num8 + 2]); a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 3], lTPCoef_Q[num8 + 3]); a2 = Inlines.silk_SMLAWB(a2, array2[num12 - 4], lTPCoef_Q[num8 + 4]); num12++; array5[num7 + i] = Inlines.silk_ADD_LSHIFT32(psDec.exc_Q14[num4 + i], a2, 1); array2[num6] = Inlines.silk_LSHIFT(array5[num7 + i], 1); num6++; } } else { array5 = psDec.exc_Q14; num7 = num4; } for (int i = 0; i < psDec.subfr_length; i++) { int a3 = Inlines.silk_RSHIFT(psDec.LPC_order, 1); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 1], array6[0]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 2], array6[1]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 3], array6[2]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 4], array6[3]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 5], array6[4]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 6], array6[5]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 7], array6[6]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 8], array6[7]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 9], array6[8]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 10], array6[9]); if (psDec.LPC_order == 16) { a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 11], array6[10]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 12], array6[11]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 13], array6[12]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 14], array6[13]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 15], array6[14]); a3 = Inlines.silk_SMLAWB(a3, array4[16 + i - 16], array6[15]); } array4[16 + i] = Inlines.silk_ADD_LSHIFT32(array5[num7 + i], a3, 4); xq[num5 + i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(array4[16 + i], b), 8)); } Arrays.MemCopy(array4, psDec.subfr_length, array4, 0, 16); num4 += psDec.subfr_length; num5 += psDec.subfr_length; } Arrays.MemCopy(array4, 0, psDec.sLPC_Q14_buf, 0, 16); } } internal static class DecodeIndices { internal static void silk_decode_indices(SilkChannelDecoder psDec, EntropyCoder psRangeDec, ReadOnlySpan frameData, int FrameIndex, int decode_LBRR, int condCoding) { short[] array = new short[psDec.LPC_order]; byte[] array2 = new byte[psDec.LPC_order]; int num = ((decode_LBRR == 0 && psDec.VAD_flags[FrameIndex] == 0) ? psRangeDec.dec_icdf(frameData, Tables.silk_type_offset_no_VAD_iCDF, 8u) : (psRangeDec.dec_icdf(frameData, Tables.silk_type_offset_VAD_iCDF, 8u) + 2)); psDec.indices.signalType = (sbyte)Inlines.silk_RSHIFT(num, 1); psDec.indices.quantOffsetType = (sbyte)(num & 1); if (condCoding == 2) { psDec.indices.GainsIndices[0] = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_delta_gain_iCDF, 8u); } else { psDec.indices.GainsIndices[0] = (sbyte)Inlines.silk_LSHIFT(psRangeDec.dec_icdf(frameData, Tables.silk_gain_iCDF[psDec.indices.signalType], 8u), 3); psDec.indices.GainsIndices[0] += (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_uniform8_iCDF, 8u); } for (int i = 1; i < psDec.nb_subfr; i++) { psDec.indices.GainsIndices[i] = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_delta_gain_iCDF, 8u); } psDec.indices.NLSFIndices[0] = (sbyte)psRangeDec.dec_icdf(frameData, psDec.psNLSF_CB.CB1_iCDF, (psDec.indices.signalType >> 1) * psDec.psNLSF_CB.nVectors, 8u); NLSF.silk_NLSF_unpack(array, array2, psDec.psNLSF_CB, psDec.indices.NLSFIndices[0]); for (int i = 0; i < psDec.psNLSF_CB.order; i++) { num = psRangeDec.dec_icdf(frameData, psDec.psNLSF_CB.ec_iCDF, array[i], 8u); switch (num) { case 0: num -= psRangeDec.dec_icdf(frameData, Tables.silk_NLSF_EXT_iCDF, 8u); break; case 8: num += psRangeDec.dec_icdf(frameData, Tables.silk_NLSF_EXT_iCDF, 8u); break; } psDec.indices.NLSFIndices[i + 1] = (sbyte)(num - 4); } if (psDec.nb_subfr == 4) { psDec.indices.NLSFInterpCoef_Q2 = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_NLSF_interpolation_factor_iCDF, 8u); } else { psDec.indices.NLSFInterpCoef_Q2 = 4; } if (psDec.indices.signalType == 2) { int num2 = 1; if (condCoding == 2 && psDec.ec_prevSignalType == 2) { int num3 = (short)psRangeDec.dec_icdf(frameData, Tables.silk_pitch_delta_iCDF, 8u); if (num3 > 0) { num3 -= 9; psDec.indices.lagIndex = (short)(psDec.ec_prevLagIndex + num3); num2 = 0; } } if (num2 != 0) { psDec.indices.lagIndex = (short)(psRangeDec.dec_icdf(frameData, Tables.silk_pitch_lag_iCDF, 8u) * Inlines.silk_RSHIFT(psDec.fs_kHz, 1)); psDec.indices.lagIndex += (short)psRangeDec.dec_icdf(frameData, psDec.pitch_lag_low_bits_iCDF, 8u); } psDec.ec_prevLagIndex = psDec.indices.lagIndex; psDec.indices.contourIndex = (sbyte)psRangeDec.dec_icdf(frameData, psDec.pitch_contour_iCDF, 8u); psDec.indices.PERIndex = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_LTP_per_index_iCDF, 8u); for (int j = 0; j < psDec.nb_subfr; j++) { psDec.indices.LTPIndex[j] = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_LTP_gain_iCDF_ptrs[psDec.indices.PERIndex], 8u); } if (condCoding == 0) { psDec.indices.LTP_scaleIndex = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_LTPscale_iCDF, 8u); } else { psDec.indices.LTP_scaleIndex = 0; } } psDec.ec_prevSignalType = psDec.indices.signalType; psDec.indices.Seed = (sbyte)psRangeDec.dec_icdf(frameData, Tables.silk_uniform4_iCDF, 8u); } } internal class DecodeParameters { internal static void silk_decode_parameters(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, int condCoding) { short[] array = new short[psDec.LPC_order]; short[] array2 = new short[psDec.LPC_order]; BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(psDec.LastGainIndex); GainQuantization.silk_gains_dequant(psDecCtrl.Gains_Q16, psDec.indices.GainsIndices, boxedValueSbyte, (condCoding == 2) ? 1 : 0, psDec.nb_subfr); psDec.LastGainIndex = boxedValueSbyte.Val; NLSF.silk_NLSF_decode(array, psDec.indices.NLSFIndices, psDec.psNLSF_CB); NLSF.silk_NLSF2A(psDecCtrl.PredCoef_Q12[1], array, psDec.LPC_order); if (psDec.first_frame_after_reset == 1) { psDec.indices.NLSFInterpCoef_Q2 = 4; } if (psDec.indices.NLSFInterpCoef_Q2 < 4) { for (int i = 0; i < psDec.LPC_order; i++) { array2[i] = (short)(psDec.prevNLSF_Q15[i] + Inlines.silk_RSHIFT(Inlines.silk_MUL(psDec.indices.NLSFInterpCoef_Q2, array[i] - psDec.prevNLSF_Q15[i]), 2)); } NLSF.silk_NLSF2A(psDecCtrl.PredCoef_Q12[0], array2, psDec.LPC_order); } else { Arrays.MemCopy(psDecCtrl.PredCoef_Q12[1], 0, psDecCtrl.PredCoef_Q12[0], 0, psDec.LPC_order); } Arrays.MemCopy(array, 0, psDec.prevNLSF_Q15, 0, psDec.LPC_order); if (psDec.lossCnt != 0) { BWExpander.silk_bwexpander(psDecCtrl.PredCoef_Q12[0], psDec.LPC_order, 63570); BWExpander.silk_bwexpander(psDecCtrl.PredCoef_Q12[1], psDec.LPC_order, 63570); } if (psDec.indices.signalType == 2) { DecodePitch.silk_decode_pitch(psDec.indices.lagIndex, psDec.indices.contourIndex, psDecCtrl.pitchL, psDec.fs_kHz, psDec.nb_subfr); sbyte[][] array3 = Tables.silk_LTP_vq_ptrs_Q7[psDec.indices.PERIndex]; int num; for (int j = 0; j < psDec.nb_subfr; j++) { num = psDec.indices.LTPIndex[j]; for (int i = 0; i < 5; i++) { psDecCtrl.LTPCoef_Q14[j * 5 + i] = (short)Inlines.silk_LSHIFT(array3[num][i], 7); } } num = psDec.indices.LTP_scaleIndex; psDecCtrl.LTP_scale_Q14 = Tables.silk_LTPScales_table_Q14[num]; } else { Arrays.MemSetInt(psDecCtrl.pitchL, 0, psDec.nb_subfr); Arrays.MemSetShort(psDecCtrl.LTPCoef_Q14, 0, 5 * psDec.nb_subfr); psDec.indices.PERIndex = 0; psDecCtrl.LTP_scale_Q14 = 0; } } } internal static class DecodePitch { internal static void silk_decode_pitch(short lagIndex, sbyte contourIndex, int[] pitch_lags, int Fs_kHz, int nb_subfr) { sbyte[][] array = ((Fs_kHz == 8) ? ((nb_subfr != 4) ? Tables.silk_CB_lags_stage2_10_ms : Tables.silk_CB_lags_stage2) : ((nb_subfr != 4) ? Tables.silk_CB_lags_stage3_10_ms : Tables.silk_CB_lags_stage3)); int num = Inlines.silk_SMULBB(2, Fs_kHz); int limit = Inlines.silk_SMULBB(18, Fs_kHz); int num2 = num + lagIndex; for (int i = 0; i < nb_subfr; i++) { pitch_lags[i] = num2 + array[i][contourIndex]; pitch_lags[i] = Inlines.silk_LIMIT(pitch_lags[i], num, limit); } } } internal static class DecodePulses { internal static void silk_decode_pulses(EntropyCoder psRangeDec, ReadOnlySpan frameData, short[] pulses, int signalType, int quantOffsetType, int frame_length) { int[] array = new int[20]; int[] array2 = new int[20]; int num = psRangeDec.dec_icdf(frameData, Tables.silk_rate_levels_iCDF[signalType >> 1], 8u); int num2 = Inlines.silk_RSHIFT(frame_length, 4); if (num2 * 16 < frame_length) { num2++; } for (int i = 0; i < num2; i++) { array2[i] = 0; array[i] = psRangeDec.dec_icdf(frameData, Tables.silk_pulses_per_block_iCDF[num], 8u); while (array[i] == 17) { array2[i]++; array[i] = psRangeDec.dec_icdf(frameData, Tables.silk_pulses_per_block_iCDF[9], (array2[i] == 10) ? 1 : 0, 8u); } } for (int i = 0; i < num2; i++) { if (array[i] > 0) { ShellCoder.silk_shell_decoder(pulses, Inlines.silk_SMULBB(i, 16), psRangeDec, frameData, array[i]); } else { Arrays.MemSetWithOffset(pulses, (short)0, Inlines.silk_SMULBB(i, 16), 16); } } for (int i = 0; i < num2; i++) { if (array2[i] <= 0) { continue; } int num3 = array2[i]; int num4 = Inlines.silk_SMULBB(i, 16); for (int j = 0; j < 16; j++) { int num5 = pulses[num4 + j]; for (int k = 0; k < num3; k++) { num5 = Inlines.silk_LSHIFT(num5, 1); num5 += psRangeDec.dec_icdf(frameData, Tables.silk_lsb_iCDF, 8u); } pulses[num4 + j] = (short)num5; } array[i] |= num3 << 5; } CodeSigns.silk_decode_signs(psRangeDec, frameData, pulses, frame_length, signalType, quantOffsetType, array); } } internal static class EncodeAPI { internal static int silk_InitEncoder(SilkEncoder encState, EncControlState encStatus) { int num = SilkError.SILK_NO_ERROR; encState.Reset(); for (int i = 0; i < 2; i++) { num += SilkEncoder.silk_init_encoder(encState.state_Fxx[i]); } encState.nChannelsAPI = 1; encState.nChannelsInternal = 1; return num + silk_QueryEncoder(encState, encStatus); } internal static int silk_QueryEncoder(SilkEncoder encState, EncControlState encStatus) { int sILK_NO_ERROR = SilkError.SILK_NO_ERROR; SilkChannelEncoder silkChannelEncoder = encState.state_Fxx[0]; encStatus.Reset(); encStatus.nChannelsAPI = encState.nChannelsAPI; encStatus.nChannelsInternal = encState.nChannelsInternal; encStatus.API_sampleRate = silkChannelEncoder.API_fs_Hz; encStatus.maxInternalSampleRate = silkChannelEncoder.maxInternal_fs_Hz; encStatus.minInternalSampleRate = silkChannelEncoder.minInternal_fs_Hz; encStatus.desiredInternalSampleRate = silkChannelEncoder.desiredInternal_fs_Hz; encStatus.payloadSize_ms = silkChannelEncoder.PacketSize_ms; encStatus.bitRate = silkChannelEncoder.TargetRate_bps; encStatus.packetLossPercentage = silkChannelEncoder.PacketLoss_perc; encStatus.complexity = silkChannelEncoder.Complexity; encStatus.useInBandFEC = silkChannelEncoder.useInBandFEC; encStatus.useDTX = silkChannelEncoder.useDTX; encStatus.useCBR = silkChannelEncoder.useCBR; encStatus.internalSampleRate = Inlines.silk_SMULBB(silkChannelEncoder.fs_kHz, 1000); encStatus.allowBandwidthSwitch = silkChannelEncoder.allow_bandwidth_switch; encStatus.inWBmodeWithoutVariableLP = ((silkChannelEncoder.fs_kHz == 16 && silkChannelEncoder.sLP.mode == 0) ? 1 : 0); return sILK_NO_ERROR; } internal static int silk_Encode(SilkEncoder psEnc, EncControlState encControl, short[] samplesIn, int nSamplesIn, EntropyCoder psRangeEnc, Span encodedDataOut, BoxedValueInt nBytesOut, int prefillFlag) { int sILK_NO_ERROR = SilkError.SILK_NO_ERROR; int payloadSize_ms = 0; int complexity = 0; int num = 0; int[] array = new int[2]; nBytesOut.Val = 0; if (encControl.reducedDependency != 0) { psEnc.state_Fxx[0].first_frame_after_reset = 1; psEnc.state_Fxx[1].first_frame_after_reset = 1; } psEnc.state_Fxx[0].nFramesEncoded = (psEnc.state_Fxx[1].nFramesEncoded = 0); sILK_NO_ERROR += encControl.check_control_input(); if (sILK_NO_ERROR != SilkError.SILK_NO_ERROR) { return sILK_NO_ERROR; } encControl.switchReady = 0; if (encControl.nChannelsInternal > psEnc.nChannelsInternal) { sILK_NO_ERROR += SilkEncoder.silk_init_encoder(psEnc.state_Fxx[1]); Arrays.MemSetShort(psEnc.sStereo.pred_prev_Q13, 0, 2); Arrays.MemSetShort(psEnc.sStereo.sSide, 0, 2); psEnc.sStereo.mid_side_amp_Q0[0] = 0; psEnc.sStereo.mid_side_amp_Q0[1] = 1; psEnc.sStereo.mid_side_amp_Q0[2] = 0; psEnc.sStereo.mid_side_amp_Q0[3] = 1; psEnc.sStereo.width_prev_Q14 = 0; psEnc.sStereo.smth_width_Q14 = 16384; if (psEnc.nChannelsAPI == 2) { psEnc.state_Fxx[1].resampler_state.Assign(psEnc.state_Fxx[0].resampler_state); Arrays.MemCopy(psEnc.state_Fxx[0].In_HP_State, 0, psEnc.state_Fxx[1].In_HP_State, 0, 2); } } int num2 = ((encControl.payloadSize_ms != psEnc.state_Fxx[0].PacketSize_ms || psEnc.nChannelsInternal != encControl.nChannelsInternal) ? 1 : 0); psEnc.nChannelsAPI = encControl.nChannelsAPI; psEnc.nChannelsInternal = encControl.nChannelsInternal; int num3 = Inlines.silk_DIV32(100 * nSamplesIn, encControl.API_sampleRate); int num4 = ((num3 <= 1) ? 1 : (num3 >> 1)); int num5 = 0; if (prefillFlag != 0) { if (num3 != 1) { return SilkError.SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } for (int i = 0; i < encControl.nChannelsInternal; i++) { sILK_NO_ERROR += SilkEncoder.silk_init_encoder(psEnc.state_Fxx[i]); } payloadSize_ms = encControl.payloadSize_ms; encControl.payloadSize_ms = 10; complexity = encControl.complexity; encControl.complexity = 0; for (int i = 0; i < encControl.nChannelsInternal; i++) { psEnc.state_Fxx[i].controlled_since_last_payload = 0; psEnc.state_Fxx[i].prefillFlag = 1; } } else { if (num3 * encControl.API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0) { return SilkError.SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } if (1000 * nSamplesIn > encControl.payloadSize_ms * encControl.API_sampleRate) { return SilkError.SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } } int targetRate_bps = Inlines.silk_RSHIFT32(encControl.bitRate, encControl.nChannelsInternal - 1); for (int i = 0; i < encControl.nChannelsInternal; i++) { int force_fs_kHz = ((i == 1) ? psEnc.state_Fxx[0].fs_kHz : 0); sILK_NO_ERROR += psEnc.state_Fxx[i].silk_control_encoder(encControl, targetRate_bps, psEnc.allowBandwidthSwitch, i, force_fs_kHz); if (sILK_NO_ERROR != SilkError.SILK_NO_ERROR) { return sILK_NO_ERROR; } if (psEnc.state_Fxx[i].first_frame_after_reset != 0 || num2 != 0) { for (int j = 0; j < psEnc.state_Fxx[0].nFramesPerPacket; j++) { psEnc.state_Fxx[i].LBRR_flags[j] = 0; } } psEnc.state_Fxx[i].inDTX = psEnc.state_Fxx[i].useDTX; } int num6 = 10 * num3 * psEnc.state_Fxx[0].fs_kHz; short[] array2 = new short[Inlines.silk_DIV32_16(num6 * psEnc.state_Fxx[0].API_fs_Hz, (short)(psEnc.state_Fxx[0].fs_kHz * 1000))]; int num7 = 0; while (true) { int a = psEnc.state_Fxx[0].frame_length - psEnc.state_Fxx[0].inputBufIx; a = Inlines.silk_min(a, num6); num = Inlines.silk_DIV32_16(a * psEnc.state_Fxx[0].API_fs_Hz, psEnc.state_Fxx[0].fs_kHz * 1000); if (encControl.nChannelsAPI == 2 && encControl.nChannelsInternal == 2) { int nFramesEncoded = psEnc.state_Fxx[0].nFramesEncoded; for (int i = 0; i < num; i++) { array2[i] = samplesIn[num7 + 2 * i]; } if (psEnc.nPrevChannelsInternal == 1 && nFramesEncoded == 0) { psEnc.state_Fxx[1].resampler_state.Assign(psEnc.state_Fxx[0].resampler_state); } sILK_NO_ERROR += Resampler.silk_resampler(psEnc.state_Fxx[0].resampler_state, psEnc.state_Fxx[0].inputBuf, psEnc.state_Fxx[0].inputBufIx + 2, array2, 0, num); psEnc.state_Fxx[0].inputBufIx += a; a = psEnc.state_Fxx[1].frame_length - psEnc.state_Fxx[1].inputBufIx; a = Inlines.silk_min(a, 10 * num3 * psEnc.state_Fxx[1].fs_kHz); for (int i = 0; i < num; i++) { array2[i] = samplesIn[num7 + 2 * i + 1]; } sILK_NO_ERROR += Resampler.silk_resampler(psEnc.state_Fxx[1].resampler_state, psEnc.state_Fxx[1].inputBuf, psEnc.state_Fxx[1].inputBufIx + 2, array2, 0, num); psEnc.state_Fxx[1].inputBufIx += a; } else if (encControl.nChannelsAPI == 2 && encControl.nChannelsInternal == 1) { for (int i = 0; i < num; i++) { int a2 = samplesIn[num7 + 2 * i] + samplesIn[num7 + 2 * i + 1]; array2[i] = (short)Inlines.silk_RSHIFT_ROUND(a2, 1); } sILK_NO_ERROR += Resampler.silk_resampler(psEnc.state_Fxx[0].resampler_state, psEnc.state_Fxx[0].inputBuf, psEnc.state_Fxx[0].inputBufIx + 2, array2, 0, num); if (psEnc.nPrevChannelsInternal == 2 && psEnc.state_Fxx[0].nFramesEncoded == 0) { sILK_NO_ERROR += Resampler.silk_resampler(psEnc.state_Fxx[1].resampler_state, psEnc.state_Fxx[1].inputBuf, psEnc.state_Fxx[1].inputBufIx + 2, array2, 0, num); for (int i = 0; i < psEnc.state_Fxx[0].frame_length; i++) { psEnc.state_Fxx[0].inputBuf[psEnc.state_Fxx[0].inputBufIx + i + 2] = (short)Inlines.silk_RSHIFT(psEnc.state_Fxx[0].inputBuf[psEnc.state_Fxx[0].inputBufIx + i + 2] + psEnc.state_Fxx[1].inputBuf[psEnc.state_Fxx[1].inputBufIx + i + 2], 1); } } psEnc.state_Fxx[0].inputBufIx += a; } else { Arrays.MemCopy(samplesIn, num7, array2, 0, num); sILK_NO_ERROR += Resampler.silk_resampler(psEnc.state_Fxx[0].resampler_state, psEnc.state_Fxx[0].inputBuf, psEnc.state_Fxx[0].inputBufIx + 2, array2, 0, num); psEnc.state_Fxx[0].inputBufIx += a; } num7 += num * encControl.nChannelsAPI; nSamplesIn -= num; psEnc.allowBandwidthSwitch = 0; if (psEnc.state_Fxx[0].inputBufIx < psEnc.state_Fxx[0].frame_length) { break; } if (psEnc.state_Fxx[0].nFramesEncoded == 0 && prefillFlag == 0) { psRangeEnc.enc_icdf(encodedDataOut, 0, new byte[2] { (byte)(256 - Inlines.silk_RSHIFT(256, (psEnc.state_Fxx[0].nFramesPerPacket + 1) * encControl.nChannelsInternal)), 0 }, 8u); for (int i = 0; i < encControl.nChannelsInternal; i++) { int num8 = 0; for (int j = 0; j < psEnc.state_Fxx[i].nFramesPerPacket; j++) { num8 |= Inlines.silk_LSHIFT(psEnc.state_Fxx[i].LBRR_flags[j], j); } psEnc.state_Fxx[i].LBRR_flag = ((num8 > 0) ? ((sbyte)1) : ((sbyte)0)); if (num8 != 0 && psEnc.state_Fxx[i].nFramesPerPacket > 1) { psRangeEnc.enc_icdf(encodedDataOut, num8 - 1, Tables.silk_LBRR_flags_iCDF_ptr[psEnc.state_Fxx[i].nFramesPerPacket - 2], 8u); } } for (int j = 0; j < psEnc.state_Fxx[0].nFramesPerPacket; j++) { for (int i = 0; i < encControl.nChannelsInternal; i++) { if (psEnc.state_Fxx[i].LBRR_flags[j] == 0) { continue; } if (encControl.nChannelsInternal == 2 && i == 0) { Stereo.silk_stereo_encode_pred(psRangeEnc, encodedDataOut, psEnc.sStereo.predIx[j]); if (psEnc.state_Fxx[1].LBRR_flags[j] == 0) { Stereo.silk_stereo_encode_mid_only(psRangeEnc, encodedDataOut, psEnc.sStereo.mid_only_flags[j]); } } EncodeIndices.silk_encode_indices(condCoding: (j > 0 && psEnc.state_Fxx[i].LBRR_flags[j - 1] != 0) ? 2 : 0, psEncC: psEnc.state_Fxx[i], psRangeEnc: psRangeEnc, encodedDataOut: encodedDataOut, FrameIndex: j, encode_LBRR: 1); EncodePulses.silk_encode_pulses(psRangeEnc, encodedDataOut, psEnc.state_Fxx[i].indices_LBRR[j].signalType, psEnc.state_Fxx[i].indices_LBRR[j].quantOffsetType, psEnc.state_Fxx[i].pulses_LBRR[j], psEnc.state_Fxx[i].frame_length); } } for (int i = 0; i < encControl.nChannelsInternal; i++) { Arrays.MemSetInt(psEnc.state_Fxx[i].LBRR_flags, 0, 3); } psEnc.nBitsUsedLBRR = psRangeEnc.tell(); } HPVariableCutoff.silk_HP_variable_cutoff(psEnc.state_Fxx); int num9 = Inlines.silk_DIV32_16(Inlines.silk_MUL(encControl.bitRate, encControl.payloadSize_ms), 1000); if (prefillFlag == 0) { num9 -= psEnc.nBitsUsedLBRR; } num9 = Inlines.silk_DIV32_16(num9, psEnc.state_Fxx[0].nFramesPerPacket); targetRate_bps = ((encControl.payloadSize_ms != 10) ? Inlines.silk_SMULBB(num9, 50) : Inlines.silk_SMULBB(num9, 100)); targetRate_bps -= Inlines.silk_DIV32_16(Inlines.silk_MUL(psEnc.nBitsExceeded, 1000), 500); if (prefillFlag == 0 && psEnc.state_Fxx[0].nFramesEncoded > 0) { int a3 = psRangeEnc.tell() - psEnc.nBitsUsedLBRR - num9 * psEnc.state_Fxx[0].nFramesEncoded; targetRate_bps -= Inlines.silk_DIV32_16(Inlines.silk_MUL(a3, 1000), 500); } targetRate_bps = Inlines.silk_LIMIT(targetRate_bps, encControl.bitRate, 5000); if (encControl.nChannelsInternal == 2) { BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(psEnc.sStereo.mid_only_flags[psEnc.state_Fxx[0].nFramesEncoded]); Stereo.silk_stereo_LR_to_MS(psEnc.sStereo, psEnc.state_Fxx[0].inputBuf, 2, psEnc.state_Fxx[1].inputBuf, 2, psEnc.sStereo.predIx[psEnc.state_Fxx[0].nFramesEncoded], boxedValueSbyte, array, targetRate_bps, psEnc.state_Fxx[0].speech_activity_Q8, encControl.toMono, psEnc.state_Fxx[0].fs_kHz, psEnc.state_Fxx[0].frame_length); psEnc.sStereo.mid_only_flags[psEnc.state_Fxx[0].nFramesEncoded] = boxedValueSbyte.Val; if (boxedValueSbyte.Val == 0) { if (psEnc.prev_decode_only_middle == 1) { psEnc.state_Fxx[1].sShape.Reset(); psEnc.state_Fxx[1].sPrefilt.Reset(); psEnc.state_Fxx[1].sNSQ.Reset(); Arrays.MemSetShort(psEnc.state_Fxx[1].prev_NLSFq_Q15, 0, 16); Arrays.MemSetInt(psEnc.state_Fxx[1].sLP.In_LP_State, 0, 2); psEnc.state_Fxx[1].prevLag = 100; psEnc.state_Fxx[1].sNSQ.lagPrev = 100; psEnc.state_Fxx[1].sShape.LastGainIndex = 10; psEnc.state_Fxx[1].prevSignalType = 0; psEnc.state_Fxx[1].sNSQ.prev_gain_Q16 = 65536; psEnc.state_Fxx[1].first_frame_after_reset = 1; } psEnc.state_Fxx[1].silk_encode_do_VAD(); } else { psEnc.state_Fxx[1].VAD_flags[psEnc.state_Fxx[0].nFramesEncoded] = 0; } if (prefillFlag == 0) { Stereo.silk_stereo_encode_pred(psRangeEnc, encodedDataOut, psEnc.sStereo.predIx[psEnc.state_Fxx[0].nFramesEncoded]); if (psEnc.state_Fxx[1].VAD_flags[psEnc.state_Fxx[0].nFramesEncoded] == 0) { Stereo.silk_stereo_encode_mid_only(psRangeEnc, encodedDataOut, psEnc.sStereo.mid_only_flags[psEnc.state_Fxx[0].nFramesEncoded]); } } } else { Arrays.MemCopy(psEnc.sStereo.sMid, 0, psEnc.state_Fxx[0].inputBuf, 0, 2); Arrays.MemCopy(psEnc.state_Fxx[0].inputBuf, psEnc.state_Fxx[0].frame_length, psEnc.sStereo.sMid, 0, 2); } psEnc.state_Fxx[0].silk_encode_do_VAD(); for (int i = 0; i < encControl.nChannelsInternal; i++) { int num10 = encControl.maxBits; if (num4 == 2 && num5 == 0) { num10 = num10 * 3 / 5; } else if (num4 == 3) { switch (num5) { case 0: num10 = num10 * 2 / 5; break; case 1: num10 = num10 * 3 / 4; break; } } int useCBR = ((encControl.useCBR != 0 && num5 == num4 - 1) ? 1 : 0); int num11; if (encControl.nChannelsInternal == 1) { num11 = targetRate_bps; } else { num11 = array[i]; if (i == 0 && array[1] > 0) { useCBR = 0; num10 -= encControl.maxBits / (num4 * 2); } } if (num11 > 0) { psEnc.state_Fxx[i].silk_control_SNR(num11); int condCoding = ((psEnc.state_Fxx[0].nFramesEncoded - i > 0) ? ((i > 0 && psEnc.prev_decode_only_middle != 0) ? 1 : 2) : 0); sILK_NO_ERROR += psEnc.state_Fxx[i].silk_encode_frame(nBytesOut, psRangeEnc, encodedDataOut, condCoding, num10, useCBR); } psEnc.state_Fxx[i].controlled_since_last_payload = 0; psEnc.state_Fxx[i].inputBufIx = 0; psEnc.state_Fxx[i].nFramesEncoded++; } psEnc.prev_decode_only_middle = psEnc.sStereo.mid_only_flags[psEnc.state_Fxx[0].nFramesEncoded - 1]; if (nBytesOut.Val > 0 && psEnc.state_Fxx[0].nFramesEncoded == psEnc.state_Fxx[0].nFramesPerPacket) { int num12 = 0; for (int i = 0; i < encControl.nChannelsInternal; i++) { for (int j = 0; j < psEnc.state_Fxx[i].nFramesPerPacket; j++) { num12 = Inlines.silk_LSHIFT(num12, 1); num12 |= psEnc.state_Fxx[i].VAD_flags[j]; } num12 = Inlines.silk_LSHIFT(num12, 1); num12 |= psEnc.state_Fxx[i].LBRR_flag; } if (prefillFlag == 0) { psRangeEnc.enc_patch_initial_bits(encodedDataOut, (uint)num12, (uint)((psEnc.state_Fxx[0].nFramesPerPacket + 1) * encControl.nChannelsInternal)); } if (psEnc.state_Fxx[0].inDTX != 0 && (encControl.nChannelsInternal == 1 || psEnc.state_Fxx[1].inDTX != 0)) { nBytesOut.Val = 0; } psEnc.nBitsExceeded += nBytesOut.Val * 8; psEnc.nBitsExceeded -= Inlines.silk_DIV32_16(Inlines.silk_MUL(encControl.bitRate, encControl.payloadSize_ms), 1000); psEnc.nBitsExceeded = Inlines.silk_LIMIT(psEnc.nBitsExceeded, 0, 10000); int num13 = Inlines.silk_SMLAWB(13, 3188, psEnc.timeSinceSwitchAllowed_ms); if (psEnc.state_Fxx[0].speech_activity_Q8 < num13) { psEnc.allowBandwidthSwitch = 1; psEnc.timeSinceSwitchAllowed_ms = 0; } else { psEnc.allowBandwidthSwitch = 0; psEnc.timeSinceSwitchAllowed_ms += encControl.payloadSize_ms; } } if (nSamplesIn == 0) { break; } num5++; } psEnc.nPrevChannelsInternal = encControl.nChannelsInternal; encControl.allowBandwidthSwitch = psEnc.allowBandwidthSwitch; encControl.inWBmodeWithoutVariableLP = ((psEnc.state_Fxx[0].fs_kHz == 16 && psEnc.state_Fxx[0].sLP.mode == 0) ? 1 : 0); encControl.internalSampleRate = Inlines.silk_SMULBB(psEnc.state_Fxx[0].fs_kHz, 1000); encControl.stereoWidth_Q14 = ((encControl.toMono == 0) ? psEnc.sStereo.smth_width_Q14 : 0); if (prefillFlag != 0) { encControl.payloadSize_ms = payloadSize_ms; encControl.complexity = complexity; for (int i = 0; i < encControl.nChannelsInternal; i++) { psEnc.state_Fxx[i].controlled_since_last_payload = 0; psEnc.state_Fxx[i].prefillFlag = 0; } } return sILK_NO_ERROR; } } internal static class EncodeIndices { internal static void silk_encode_indices(SilkChannelEncoder psEncC, EntropyCoder psRangeEnc, Span encodedDataOut, int FrameIndex, int encode_LBRR, int condCoding) { short[] array = new short[16]; byte[] array2 = new byte[16]; SideInfoIndices sideInfoIndices = ((encode_LBRR == 0) ? psEncC.indices : psEncC.indices_LBRR[FrameIndex]); int num = 2 * sideInfoIndices.signalType + sideInfoIndices.quantOffsetType; if (encode_LBRR != 0 || num >= 2) { psRangeEnc.enc_icdf(encodedDataOut, num - 2, Tables.silk_type_offset_VAD_iCDF, 8u); } else { psRangeEnc.enc_icdf(encodedDataOut, num, Tables.silk_type_offset_no_VAD_iCDF, 8u); } if (condCoding == 2) { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.GainsIndices[0], Tables.silk_delta_gain_iCDF, 8u); } else { psRangeEnc.enc_icdf(encodedDataOut, Inlines.silk_RSHIFT(sideInfoIndices.GainsIndices[0], 3), Tables.silk_gain_iCDF[sideInfoIndices.signalType], 8u); psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.GainsIndices[0] & 7, Tables.silk_uniform8_iCDF, 8u); } for (int i = 1; i < psEncC.nb_subfr; i++) { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.GainsIndices[i], Tables.silk_delta_gain_iCDF, 8u); } psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.NLSFIndices[0], psEncC.psNLSF_CB.CB1_iCDF, (sideInfoIndices.signalType >> 1) * psEncC.psNLSF_CB.nVectors, 8u); NLSF.silk_NLSF_unpack(array, array2, psEncC.psNLSF_CB, sideInfoIndices.NLSFIndices[0]); for (int i = 0; i < psEncC.psNLSF_CB.order; i++) { if (sideInfoIndices.NLSFIndices[i + 1] >= 4) { psRangeEnc.enc_icdf(encodedDataOut, 8, psEncC.psNLSF_CB.ec_iCDF, array[i], 8u); psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.NLSFIndices[i + 1] - 4, Tables.silk_NLSF_EXT_iCDF, 8u); } else if (sideInfoIndices.NLSFIndices[i + 1] <= -4) { psRangeEnc.enc_icdf(encodedDataOut, 0, psEncC.psNLSF_CB.ec_iCDF, array[i], 8u); psRangeEnc.enc_icdf(encodedDataOut, -sideInfoIndices.NLSFIndices[i + 1] - 4, Tables.silk_NLSF_EXT_iCDF, 8u); } else { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.NLSFIndices[i + 1] + 4, psEncC.psNLSF_CB.ec_iCDF, array[i], 8u); } } if (psEncC.nb_subfr == 4) { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.NLSFInterpCoef_Q2, Tables.silk_NLSF_interpolation_factor_iCDF, 8u); } if (sideInfoIndices.signalType == 2) { int num2 = 1; if (condCoding == 2 && psEncC.ec_prevSignalType == 2) { int num3 = sideInfoIndices.lagIndex - psEncC.ec_prevLagIndex; if (num3 < -8 || num3 > 11) { num3 = 0; } else { num3 += 9; num2 = 0; } psRangeEnc.enc_icdf(encodedDataOut, num3, Tables.silk_pitch_delta_iCDF, 8u); } if (num2 != 0) { int num4 = Inlines.silk_DIV32_16(sideInfoIndices.lagIndex, Inlines.silk_RSHIFT(psEncC.fs_kHz, 1)); int s = sideInfoIndices.lagIndex - Inlines.silk_SMULBB(num4, Inlines.silk_RSHIFT(psEncC.fs_kHz, 1)); psRangeEnc.enc_icdf(encodedDataOut, num4, Tables.silk_pitch_lag_iCDF, 8u); psRangeEnc.enc_icdf(encodedDataOut, s, psEncC.pitch_lag_low_bits_iCDF, 8u); } psEncC.ec_prevLagIndex = sideInfoIndices.lagIndex; psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.contourIndex, psEncC.pitch_contour_iCDF, 8u); psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.PERIndex, Tables.silk_LTP_per_index_iCDF, 8u); for (int j = 0; j < psEncC.nb_subfr; j++) { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.LTPIndex[j], Tables.silk_LTP_gain_iCDF_ptrs[sideInfoIndices.PERIndex], 8u); } if (condCoding == 0) { psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.LTP_scaleIndex, Tables.silk_LTPscale_iCDF, 8u); } } psEncC.ec_prevSignalType = sideInfoIndices.signalType; psRangeEnc.enc_icdf(encodedDataOut, sideInfoIndices.Seed, Tables.silk_uniform4_iCDF, 8u); } } internal static class EncodePulses { internal static int combine_and_check(Span pulses_comb, int pulses_comb_ptr, Span pulses_in, int pulses_in_ptr, int max_pulses, int len) { for (int i = 0; i < len; i++) { int num = 2 * i + pulses_in_ptr; int num2 = pulses_in[num] + pulses_in[num + 1]; if (num2 > max_pulses) { return 1; } pulses_comb[pulses_comb_ptr + i] = num2; } return 0; } internal static int combine_and_check(int[] pulses_comb, int[] pulses_in, int max_pulses, int len) { for (int i = 0; i < len; i++) { int num = pulses_in[2 * i] + pulses_in[2 * i + 1]; if (num > max_pulses) { return 1; } pulses_comb[i] = num; } return 0; } internal static void silk_encode_pulses(EntropyCoder psRangeEnc, Span encodedDataOut, int signalType, int quantOffsetType, Span pulses, int frame_length) { int num = 0; int[] array = new int[8]; Arrays.MemSetInt(array, 0, 8); int num2 = Inlines.silk_RSHIFT(frame_length, 4); if (num2 * 16 < frame_length) { num2++; Arrays.MemSetWithOffset(pulses, 0, frame_length, 16); } int[] array2 = new int[num2 * 16]; for (int i = 0; i < num2 * 16; i += 4) { array2[i] = Inlines.silk_abs(pulses[i]); array2[i + 1] = Inlines.silk_abs(pulses[i + 1]); array2[i + 2] = Inlines.silk_abs(pulses[i + 2]); array2[i + 3] = Inlines.silk_abs(pulses[i + 3]); } int[] array3 = new int[num2]; int[] array4 = new int[num2]; int num3 = 0; for (int i = 0; i < num2; i++) { array4[i] = 0; while (combine_and_check(array, 0, array2, num3, Tables.silk_max_pulses_table[0], 8) + combine_and_check(array, array, Tables.silk_max_pulses_table[1], 4) + combine_and_check(array, array, Tables.silk_max_pulses_table[2], 2) + combine_and_check(array3, i, array, 0, Tables.silk_max_pulses_table[3], 1) != 0) { array4[i]++; for (int j = num3; j < num3 + 16; j++) { array2[j] = Inlines.silk_RSHIFT(array2[j], 1); } } num3 += 16; } int num4 = int.MaxValue; for (int j = 0; j < 9; j++) { byte[] array5 = Tables.silk_pulses_per_block_BITS_Q5[j]; int num5 = Tables.silk_rate_levels_BITS_Q5[signalType >> 1][j]; for (int i = 0; i < num2; i++) { num5 = ((array4[i] <= 0) ? (num5 + array5[array3[i]]) : (num5 + array5[17])); } if (num5 < num4) { num4 = num5; num = j; } } psRangeEnc.enc_icdf(encodedDataOut, num, Tables.silk_rate_levels_iCDF[signalType >> 1], 8u); for (int i = 0; i < num2; i++) { if (array4[i] == 0) { psRangeEnc.enc_icdf(encodedDataOut, array3[i], Tables.silk_pulses_per_block_iCDF[num], 8u); continue; } psRangeEnc.enc_icdf(encodedDataOut, 17, Tables.silk_pulses_per_block_iCDF[num], 8u); for (int j = 0; j < array4[i] - 1; j++) { psRangeEnc.enc_icdf(encodedDataOut, 17, Tables.silk_pulses_per_block_iCDF[9], 8u); } psRangeEnc.enc_icdf(encodedDataOut, array3[i], Tables.silk_pulses_per_block_iCDF[9], 8u); } for (int i = 0; i < num2; i++) { if (array3[i] > 0) { ShellCoder.silk_shell_encoder(psRangeEnc, encodedDataOut, array2, i * 16); } } for (int i = 0; i < num2; i++) { if (array4[i] <= 0) { continue; } int num6 = i * 16; int num7 = array4[i] - 1; for (int j = 0; j < 16; j++) { int num8 = (sbyte)Inlines.silk_abs(pulses[num6 + j]); int s; for (int num9 = num7; num9 > 0; num9--) { s = Inlines.silk_RSHIFT(num8, num9) & 1; psRangeEnc.enc_icdf(encodedDataOut, s, Tables.silk_lsb_iCDF, 8u); } s = num8 & 1; psRangeEnc.enc_icdf(encodedDataOut, s, Tables.silk_lsb_iCDF, 8u); } } CodeSigns.silk_encode_signs(psRangeEnc, encodedDataOut, pulses, frame_length, signalType, quantOffsetType, array3); } } internal static class Filters { private static readonly short A_fb1_20 = 10788; private static readonly short A_fb1_21 = -24290; private const int QA = 24; private static readonly int A_LIMIT = 16773022; internal static void silk_warped_LPC_analysis_filter(int[] state, int[] res_Q2, short[] coef_Q13, int coef_Q13_ptr, short[] input, int input_ptr, short lambda_Q16, int length, int order) { for (int i = 0; i < length; i++) { int num = Inlines.silk_SMLAWB(state[0], state[1], lambda_Q16); state[0] = Inlines.silk_LSHIFT(input[input_ptr + i], 14); int num2 = Inlines.silk_SMLAWB(state[1], state[2] - num, lambda_Q16); state[1] = num; int a = Inlines.silk_RSHIFT(order, 1); a = Inlines.silk_SMLAWB(a, num, coef_Q13[coef_Q13_ptr]); for (int j = 2; j < order; j += 2) { num = Inlines.silk_SMLAWB(state[j], state[j + 1] - num2, lambda_Q16); state[j] = num2; a = Inlines.silk_SMLAWB(a, num2, coef_Q13[coef_Q13_ptr + j - 1]); num2 = Inlines.silk_SMLAWB(state[j + 1], state[j + 2] - num, lambda_Q16); state[j + 1] = num; a = Inlines.silk_SMLAWB(a, num, coef_Q13[coef_Q13_ptr + j]); } state[order] = num2; a = Inlines.silk_SMLAWB(a, num2, coef_Q13[coef_Q13_ptr + order - 1]); res_Q2[i] = Inlines.silk_LSHIFT(input[input_ptr + i], 2) - Inlines.silk_RSHIFT_ROUND(a, 9); } } internal static void silk_prefilter(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, int[] xw_Q3, short[] x, int x_ptr) { SilkPrefilterState sPrefilt = psEnc.sPrefilt; Span span = stackalloc short[2]; int num = x_ptr; int num2 = 0; int lag = sPrefilt.lagPrev; int[] array = new int[psEnc.subfr_length]; int[] array2 = new int[psEnc.subfr_length]; for (int i = 0; i < psEnc.nb_subfr; i++) { if (psEnc.indices.signalType == 2) { lag = psEncCtrl.pitchL[i]; } int num3 = Inlines.silk_SMULWB(psEncCtrl.HarmShapeGain_Q14[i], 16384 - psEncCtrl.HarmBoost_Q14[i]); int num4 = Inlines.silk_RSHIFT(num3, 2); num4 |= Inlines.silk_LSHIFT(Inlines.silk_RSHIFT(num3, 1), 16); int tilt_Q = psEncCtrl.Tilt_Q14[i]; int lF_shp_Q = psEncCtrl.LF_shp_Q14[i]; int coef_Q13_ptr = i * 16; silk_warped_LPC_analysis_filter(sPrefilt.sAR_shp, array2, psEncCtrl.AR1_Q13, coef_Q13_ptr, x, num, (short)psEnc.warping_Q16, psEnc.subfr_length, psEnc.shapingLPCOrder); span[0] = (short)Inlines.silk_RSHIFT_ROUND(psEncCtrl.GainsPre_Q14[i], 4); int a = Inlines.silk_SMLABB(3355443, psEncCtrl.HarmBoost_Q14[i], num3); a = Inlines.silk_SMLABB(a, psEncCtrl.coding_quality_Q14, 410); a = Inlines.silk_SMULWB(a, -psEncCtrl.GainsPre_Q14[i]); a = Inlines.silk_RSHIFT_ROUND(a, 14); span[1] = (short)Inlines.silk_SAT16(a); array[0] = Inlines.silk_MLA(Inlines.silk_MUL(array2[0], span[0]), sPrefilt.sHarmHP_Q2, span[1]); for (int j = 1; j < psEnc.subfr_length; j++) { array[j] = Inlines.silk_MLA(Inlines.silk_MUL(array2[j], span[0]), array2[j - 1], span[1]); } sPrefilt.sHarmHP_Q2 = array2[psEnc.subfr_length - 1]; silk_prefilt(sPrefilt, array, xw_Q3, num2, num4, tilt_Q, lF_shp_Q, lag, psEnc.subfr_length); num += psEnc.subfr_length; num2 += psEnc.subfr_length; } sPrefilt.lagPrev = psEncCtrl.pitchL[psEnc.nb_subfr - 1]; } private static void silk_prefilt(SilkPrefilterState P, int[] st_res_Q12, int[] xw_Q3, int xw_Q3_ptr, int HarmShapeFIRPacked_Q12, int Tilt_Q14, int LF_shp_Q14, int lag, int length) { short[] sLTP_shp = P.sLTP_shp; int num = P.sLTP_shp_buf_idx; int num2 = P.sLF_AR_shp_Q12; int num3 = P.sLF_MA_shp_Q12; for (int i = 0; i < length; i++) { int a; if (lag > 0) { int num4 = lag + num; a = Inlines.silk_SMULBB(sLTP_shp[(num4 - 1 - 1) & 0x1FF], HarmShapeFIRPacked_Q12); a = Inlines.silk_SMLABT(a, sLTP_shp[(num4 - 1) & 0x1FF], HarmShapeFIRPacked_Q12); a = Inlines.silk_SMLABB(a, sLTP_shp[(num4 - 1 + 1) & 0x1FF], HarmShapeFIRPacked_Q12); } else { a = 0; } int a2 = Inlines.silk_SMULWB(num2, Tilt_Q14); int a3 = Inlines.silk_SMLAWB(Inlines.silk_SMULWT(num2, LF_shp_Q14), num3, LF_shp_Q14); num2 = Inlines.silk_SUB32(st_res_Q12[i], Inlines.silk_LSHIFT(a2, 2)); num3 = Inlines.silk_SUB32(num2, Inlines.silk_LSHIFT(a3, 2)); num = (num - 1) & 0x1FF; sLTP_shp[num] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(num3, 12)); xw_Q3[xw_Q3_ptr + i] = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SUB32(num3, a), 9); } P.sLF_AR_shp_Q12 = num2; P.sLF_MA_shp_Q12 = num3; P.sLTP_shp_buf_idx = num; } internal static void silk_biquad_alt(ReadOnlySpan input, int input_ptr, int[] B_Q28, int[] A_Q28, int[] S, Span output, int output_ptr, int len, int stride) { int b = -A_Q28[0] & 0x3FFF; int c = Inlines.silk_RSHIFT(-A_Q28[0], 14); int b2 = -A_Q28[1] & 0x3FFF; int c2 = Inlines.silk_RSHIFT(-A_Q28[1], 14); for (int i = 0; i < len; i++) { int c3 = input[input_ptr + i * stride]; int num = Inlines.silk_LSHIFT(Inlines.silk_SMLAWB(S[0], B_Q28[0], c3), 2); S[0] = S[1] + Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWB(num, b), 14); S[0] = Inlines.silk_SMLAWB(S[0], num, c); S[0] = Inlines.silk_SMLAWB(S[0], B_Q28[1], c3); S[1] = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWB(num, b2), 14); S[1] = Inlines.silk_SMLAWB(S[1], num, c2); S[1] = Inlines.silk_SMLAWB(S[1], B_Q28[2], c3); output[output_ptr + i * stride] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT(num + 16384 - 1, 14)); } } internal static void silk_biquad_alt(ReadOnlySpan input, int input_ptr, int[] B_Q28, int[] A_Q28, Span S, int S_ptr, Span output, int output_ptr, int len, int stride) { int b = -A_Q28[0] & 0x3FFF; int c = Inlines.silk_RSHIFT(-A_Q28[0], 14); int b2 = -A_Q28[1] & 0x3FFF; int c2 = Inlines.silk_RSHIFT(-A_Q28[1], 14); for (int i = 0; i < len; i++) { int index = S_ptr + 1; int c3 = input[input_ptr + i * stride]; int num = Inlines.silk_LSHIFT(Inlines.silk_SMLAWB(S[S_ptr], B_Q28[0], c3), 2); S[S_ptr] = S[index] + Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWB(num, b), 14); S[S_ptr] = Inlines.silk_SMLAWB(S[S_ptr], num, c); S[S_ptr] = Inlines.silk_SMLAWB(S[S_ptr], B_Q28[1], c3); S[index] = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWB(num, b2), 14); S[index] = Inlines.silk_SMLAWB(S[index], num, c2); S[index] = Inlines.silk_SMLAWB(S[index], B_Q28[2], c3); output[output_ptr + i * stride] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT(num + 16384 - 1, 14)); } } internal static void silk_ana_filt_bank_1(Span input, int input_ptr, int[] S, short[] outL, Span outH, int outH_ptr, int N) { int num = Inlines.silk_RSHIFT(N, 1); for (int i = 0; i < num; i++) { int a = Inlines.silk_LSHIFT(input[input_ptr + 2 * i], 10); int num2 = Inlines.silk_SUB32(a, S[0]); int b = Inlines.silk_SMLAWB(num2, num2, A_fb1_21); int b2 = Inlines.silk_ADD32(S[0], b); S[0] = Inlines.silk_ADD32(a, b); a = Inlines.silk_LSHIFT(input[input_ptr + 2 * i + 1], 10); b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a, S[1]), A_fb1_20); int a2 = Inlines.silk_ADD32(S[1], b); S[1] = Inlines.silk_ADD32(a, b); outL[i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_ADD32(a2, b2), 11)); outH[outH_ptr + i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SUB32(a2, b2), 11)); } } internal static void silk_bwexpander_32(int[] ar, int d, int chirp_Q16) { int b = chirp_Q16 - 65536; for (int i = 0; i < d - 1; i++) { ar[i] = Inlines.silk_SMULWW(chirp_Q16, ar[i]); chirp_Q16 += Inlines.silk_RSHIFT_ROUND(Inlines.silk_MUL(chirp_Q16, b), 16); } ar[d - 1] = Inlines.silk_SMULWW(chirp_Q16, ar[d - 1]); } internal static void silk_LP_interpolate_filter_taps(int[] B_Q28, int[] A_Q28, int ind, int fac_Q16) { if (ind < 4) { if (fac_Q16 > 0) { if (fac_Q16 < 32768) { for (int i = 0; i < 3; i++) { B_Q28[i] = Inlines.silk_SMLAWB(Tables.silk_Transition_LP_B_Q28[ind][i], Tables.silk_Transition_LP_B_Q28[ind + 1][i] - Tables.silk_Transition_LP_B_Q28[ind][i], fac_Q16); } for (int j = 0; j < 2; j++) { A_Q28[j] = Inlines.silk_SMLAWB(Tables.silk_Transition_LP_A_Q28[ind][j], Tables.silk_Transition_LP_A_Q28[ind + 1][j] - Tables.silk_Transition_LP_A_Q28[ind][j], fac_Q16); } } else { for (int i = 0; i < 3; i++) { B_Q28[i] = Inlines.silk_SMLAWB(Tables.silk_Transition_LP_B_Q28[ind + 1][i], Tables.silk_Transition_LP_B_Q28[ind + 1][i] - Tables.silk_Transition_LP_B_Q28[ind][i], fac_Q16 - 65536); } for (int j = 0; j < 2; j++) { A_Q28[j] = Inlines.silk_SMLAWB(Tables.silk_Transition_LP_A_Q28[ind + 1][j], Tables.silk_Transition_LP_A_Q28[ind + 1][j] - Tables.silk_Transition_LP_A_Q28[ind][j], fac_Q16 - 65536); } } } else { Arrays.MemCopy(Tables.silk_Transition_LP_B_Q28[ind], 0, B_Q28, 0, 3); Arrays.MemCopy(Tables.silk_Transition_LP_A_Q28[ind], 0, A_Q28, 0, 2); } } else { Arrays.MemCopy(Tables.silk_Transition_LP_B_Q28[4], 0, B_Q28, 0, 3); Arrays.MemCopy(Tables.silk_Transition_LP_A_Q28[4], 0, A_Q28, 0, 2); } } internal static void silk_LPC_analysis_filter(Span output, int output_ptr, Span input, int input_ptr, Span B, int B_ptr, int len, int d) { Span mem = stackalloc short[16]; Span num = stackalloc short[16]; for (int i = 0; i < d; i++) { num[i] = (short)(-B[B_ptr + i]); } for (int i = 0; i < d; i++) { mem[i] = input[input_ptr + d - i - 1]; } Kernels.celt_fir(input.Slice(input_ptr + d), num, output.Slice(output_ptr + d), len - d, d, mem); for (int i = output_ptr; i < output_ptr + d; i++) { output[i] = 0; } } internal static int LPC_inverse_pred_gain_QA(int[][] A_QA, int order) { int[] array = A_QA[order & 1]; int a = 1073741824; int num2; int num3; for (int num = order - 1; num > 0; num--) { if (array[num] > A_LIMIT || array[num] < -A_LIMIT) { return 0; } num2 = -Inlines.silk_LSHIFT(array[num], 7); num3 = 1073741824 - Inlines.silk_SMMUL(num2, num2); int num4 = 32 - Inlines.silk_CLZ32(Inlines.silk_abs(num3)); int b = Inlines.silk_INVERSE32_varQ(num3, num4 + 30); a = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(a, num3), 2); int[] array2 = array; array = A_QA[num & 1]; for (int i = 0; i < num; i++) { int a2 = array2[i] - Inlines.MUL32_FRAC_Q(array2[num - i - 1], num2, 31); array[i] = Inlines.MUL32_FRAC_Q(a2, b, num4); } } if (array[0] > A_LIMIT || array[0] < -A_LIMIT) { return 0; } num2 = -Inlines.silk_LSHIFT(array[0], 7); num3 = 1073741824 - Inlines.silk_SMMUL(num2, num2); return Inlines.silk_LSHIFT(Inlines.silk_SMMUL(a, num3), 2); } internal static int silk_LPC_inverse_pred_gain(short[] A_Q12, int order) { int[][] array = new int[2][] { new int[order], new int[order] }; int num = 0; int[] array2 = array[order & 1]; for (int i = 0; i < order; i++) { num += A_Q12[i]; array2[i] = Inlines.silk_LSHIFT32(A_Q12[i], 12); } if (num >= 4096) { return 0; } return LPC_inverse_pred_gain_QA(array, order); } } internal static class FindLPC { internal static void silk_find_LPC(SilkChannelEncoder psEncC, short[] NLSF_Q15, short[] x, int minInvGain_Q30) { int[] a_Q = new int[16]; BoxedValueInt boxedValueInt = new BoxedValueInt(); BoxedValueInt boxedValueInt2 = new BoxedValueInt(); int[] a_Q2 = new int[16]; short[] array = new short[16]; short[] array2 = new short[16]; int num = psEncC.subfr_length + psEncC.predictLPCOrder; psEncC.indices.NLSFInterpCoef_Q2 = 4; BurgModified.silk_burg_modified(boxedValueInt, boxedValueInt2, a_Q, x, 0, minInvGain_Q30, num, psEncC.nb_subfr, psEncC.predictLPCOrder); int num2 = boxedValueInt.Val; int num3 = boxedValueInt2.Val; if (psEncC.useInterpolatedNLSFs != 0 && psEncC.first_frame_after_reset == 0 && psEncC.nb_subfr == 4) { BurgModified.silk_burg_modified(boxedValueInt, boxedValueInt2, a_Q2, x, 2 * num, minInvGain_Q30, num, 2, psEncC.predictLPCOrder); int val = boxedValueInt.Val; int val2 = boxedValueInt2.Val; int num4 = val2 - num3; if (num4 >= 0) { if (num4 < 32) { num2 -= Inlines.silk_RSHIFT(val, num4); } } else { num2 = Inlines.silk_RSHIFT(num2, -num4) - val; num3 = val2; } NLSF.silk_A2NLSF(NLSF_Q15, a_Q2, psEncC.predictLPCOrder); short[] array3 = new short[2 * num]; for (int num5 = 3; num5 >= 0; num5--) { Inlines.silk_interpolate(array2, psEncC.prev_NLSFq_Q15, NLSF_Q15, num5, psEncC.predictLPCOrder); NLSF.silk_NLSF2A(array, array2, psEncC.predictLPCOrder); Filters.silk_LPC_analysis_filter(array3, 0, x, 0, array, 0, 2 * num, psEncC.predictLPCOrder); SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, array3, psEncC.predictLPCOrder, num - psEncC.predictLPCOrder); SumSqrShift.silk_sum_sqr_shift(out var energy2, out var shift2, array3, psEncC.predictLPCOrder + num, num - psEncC.predictLPCOrder); num4 = shift - shift2; int num6; if (num4 >= 0) { energy2 = Inlines.silk_RSHIFT(energy2, num4); num6 = -shift; } else { energy = Inlines.silk_RSHIFT(energy, -num4); num6 = -shift2; } int num7 = Inlines.silk_ADD32(energy, energy2); num4 = num6 - num3; int num8 = ((num4 >= 0) ? ((Inlines.silk_RSHIFT(num7, num4) < num2) ? 1 : 0) : ((-num4 < 32) ? ((num7 < Inlines.silk_RSHIFT(num2, -num4)) ? 1 : 0) : 0)); if (num8 == 1) { num2 = num7; num3 = num6; psEncC.indices.NLSFInterpCoef_Q2 = (sbyte)num5; } } } if (psEncC.indices.NLSFInterpCoef_Q2 == 4) { NLSF.silk_A2NLSF(NLSF_Q15, a_Q, psEncC.predictLPCOrder); } } } internal static class FindLTP { private const int LTP_CORRS_HEAD_ROOM = 2; internal static void silk_find_LTP(short[] b_Q14, int[] WLTP, BoxedValueInt LTPredCodGain_Q7, short[] r_lpc, int[] lag, int[] Wght_Q15, int subfr_length, int nb_subfr, int mem_offset, int[] corr_rshifts) { int[] array = new int[5]; int[] array2 = new int[5]; int[] array3 = new int[4]; int[] array4 = new int[4]; int[] array5 = new int[4]; int[] array6 = new int[5]; int[] array7 = new int[4]; int num = 0; int num2 = 0; int num3 = mem_offset; int num5; int a3; for (int i = 0; i < nb_subfr; i++) { int x_ptr = num3 - (lag[i] + 2); SumSqrShift.silk_sum_sqr_shift(out array7[i], out var shift, r_lpc, num3, subfr_length); int num4 = Inlines.silk_CLZ32(array7[i]); if (num4 < 2) { array7[i] = Inlines.silk_RSHIFT_ROUND(array7[i], 2 - num4); shift += 2 - num4; } corr_rshifts[i] = shift; BoxedValueInt boxedValueInt = new BoxedValueInt(corr_rshifts[i]); CorrelateMatrix.silk_corrMatrix(r_lpc, x_ptr, subfr_length, 5, 2, WLTP, num2, boxedValueInt); corr_rshifts[i] = boxedValueInt.Val; CorrelateMatrix.silk_corrVector(r_lpc, x_ptr, r_lpc, num3, subfr_length, 5, array6, corr_rshifts[i]); if (corr_rshifts[i] > shift) { array7[i] = Inlines.silk_RSHIFT(array7[i], corr_rshifts[i] - shift); } int a = 1; a = Inlines.silk_SMLAWB(a, array7[i], 1092); a = Inlines.silk_SMLAWB(a, Inlines.MatrixGet(WLTP, num2, 0, 0, 5), 1092); a = Inlines.silk_SMLAWB(a, Inlines.MatrixGet(WLTP, num2, 4, 4, 5), 1092); RegularizeCorrelations.silk_regularize_correlations(WLTP, num2, array7, i, a, 5); LinearAlgebra.silk_solve_LDL(WLTP, num2, 5, array6, array); silk_fit_LTP(array, b_Q14, num); array4[i] = ResidualEnergy.silk_residual_energy16_covar(b_Q14, num, WLTP, num2, array6, array7[i], 5, 14); num5 = Inlines.silk_min_int(corr_rshifts[i], 2); int a2 = Inlines.silk_LSHIFT_SAT32(Inlines.silk_SMULWB(array4[i], Wght_Q15[i]), 1 + num5) + Inlines.silk_RSHIFT(Inlines.silk_SMULWB(subfr_length, 655), corr_rshifts[i] - num5); a2 = Inlines.silk_max(a2, 1); a3 = Inlines.silk_DIV32(Inlines.silk_LSHIFT(Wght_Q15[i], 16), a2); a3 = Inlines.silk_RSHIFT(a3, 31 + corr_rshifts[i] - num5 - 26); int num6 = 0; for (int j = num2; j < num2 + 25; j++) { num6 = Inlines.silk_max(WLTP[j], num6); } int num7 = Inlines.silk_CLZ32(num6) - 1 - 3; if (8 + num7 < 31) { a3 = Inlines.silk_min_32(a3, Inlines.silk_LSHIFT(1, 8 + num7)); } Inlines.silk_scale_vector32_Q26_lshift_18(WLTP, num2, a3, 25); array5[i] = Inlines.MatrixGet(WLTP, num2, 2, 2, 5); num3 += subfr_length; num += 5; num2 += 25; } int num8 = 0; for (int i = 0; i < nb_subfr; i++) { num8 = Inlines.silk_max_int(corr_rshifts[i], num8); } if (LTPredCodGain_Q7 != null) { int a4 = 0; int num9 = 0; for (int i = 0; i < nb_subfr; i++) { num9 = Inlines.silk_ADD32(num9, Inlines.silk_RSHIFT(Inlines.silk_ADD32(Inlines.silk_SMULWB(array7[i], Wght_Q15[i]), 1), 1 + (num8 - corr_rshifts[i]))); a4 = Inlines.silk_ADD32(a4, Inlines.silk_RSHIFT(Inlines.silk_ADD32(Inlines.silk_SMULWB(array4[i], Wght_Q15[i]), 1), 1 + (num8 - corr_rshifts[i]))); } a4 = Inlines.silk_max(a4, 1); int inLin = Inlines.silk_DIV32_varQ(num9, a4, 16); LTPredCodGain_Q7.Val = Inlines.silk_SMULBB(3, Inlines.silk_lin2log(inLin) - 2048); } num = 0; for (int i = 0; i < nb_subfr; i++) { array3[i] = 0; for (int j = num; j < num + 5; j++) { array3[i] += b_Q14[j]; } num += 5; } int num10 = 0; int num11 = 0; for (int i = 0; i < nb_subfr; i++) { num10 = Inlines.silk_max_32(num10, Inlines.silk_abs(array3[i])); num11 = Inlines.silk_max_32(num11, 32 - Inlines.silk_CLZ32(array5[i]) + corr_rshifts[i] - num8); } num5 = num11 + 32 - Inlines.silk_CLZ32(num10) - 14; num5 -= 29 + num8; num5 = Inlines.silk_max_int(num5, 0); int num12 = num8 + num5; a3 = Inlines.silk_RSHIFT(262, num8 + num5) + 1; int num13 = 0; for (int i = 0; i < nb_subfr; i++) { a3 = Inlines.silk_ADD32(a3, Inlines.silk_RSHIFT(array5[i], num12 - corr_rshifts[i])); num13 = Inlines.silk_ADD32(num13, Inlines.silk_LSHIFT(Inlines.silk_SMULWW(Inlines.silk_RSHIFT(array5[i], num12 - corr_rshifts[i]), array3[i]), 2)); } int a5 = Inlines.silk_DIV32_varQ(num13, a3, 12); num = 0; for (int i = 0; i < nb_subfr; i++) { a3 = ((2 - corr_rshifts[i] <= 0) ? Inlines.silk_LSHIFT_SAT32(array5[i], corr_rshifts[i] - 2) : Inlines.silk_RSHIFT(array5[i], 2 - corr_rshifts[i])); int a6 = Inlines.silk_MUL(Inlines.silk_DIV32(6710887, Inlines.silk_RSHIFT(6710887, 10) + a3), Inlines.silk_LSHIFT_SAT32(Inlines.silk_SUB_SAT32(a5, Inlines.silk_RSHIFT(array3[i], 2)), 4)); a3 = 0; for (int j = 0; j < 5; j++) { array2[j] = Inlines.silk_max_16(b_Q14[num + j], 1638); a3 += array2[j]; } a3 = Inlines.silk_DIV32(a6, a3); for (int j = 0; j < 5; j++) { b_Q14[num + j] = (short)Inlines.silk_LIMIT_32(b_Q14[num + j] + Inlines.silk_SMULWB(Inlines.silk_LSHIFT_SAT32(a3, 4), array2[j]), -16000, 28000); } num += 5; } } internal static void silk_fit_LTP(int[] LTP_coefs_Q16, Span LTP_coefs_Q14, int LTP_coefs_Q14_ptr) { for (int i = 0; i < 5; i++) { LTP_coefs_Q14[LTP_coefs_Q14_ptr + i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(LTP_coefs_Q16[i], 2)); } } } internal static class FindPitchLags { internal static void silk_find_pitch_lags(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, short[] res, short[] x, int x_ptr) { int[] array = new int[17]; short[] rc_Q = new short[16]; int[] array2 = new int[16]; short[] array3 = new short[16]; int num = psEnc.la_pitch + psEnc.frame_length + psEnc.ltp_mem_length; int num2 = x_ptr - psEnc.ltp_mem_length; short[] array4 = new short[psEnc.pitch_LPC_win_length]; int num3 = num2 + num - psEnc.pitch_LPC_win_length; int num4 = 0; ApplySineWindow.silk_apply_sine_window(array4, num4, x, num3, 1, psEnc.la_pitch); num4 += psEnc.la_pitch; num3 += psEnc.la_pitch; Arrays.MemCopy(x, num3, array4, num4, psEnc.pitch_LPC_win_length - Inlines.silk_LSHIFT(psEnc.la_pitch, 1)); num4 += psEnc.pitch_LPC_win_length - Inlines.silk_LSHIFT(psEnc.la_pitch, 1); num3 += psEnc.pitch_LPC_win_length - Inlines.silk_LSHIFT(psEnc.la_pitch, 1); ApplySineWindow.silk_apply_sine_window(array4, num4, x, num3, 2, psEnc.la_pitch); Autocorrelation.silk_autocorr(array, out var _, array4, psEnc.pitch_LPC_win_length, psEnc.pitchEstimationLPCOrder + 1); array[0] = Inlines.silk_SMLAWB(array[0], array[0], 66) + 1; int a = Schur.silk_schur(rc_Q, array, psEnc.pitchEstimationLPCOrder); psEncCtrl.predGain_Q16 = Inlines.silk_DIV32_varQ(array[0], Inlines.silk_max_int(a, 1), 16); K2A.silk_k2a(array2, rc_Q, psEnc.pitchEstimationLPCOrder); for (int i = 0; i < psEnc.pitchEstimationLPCOrder; i++) { array3[i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT(array2[i], 12)); } BWExpander.silk_bwexpander(array3, psEnc.pitchEstimationLPCOrder, 64881); Filters.silk_LPC_analysis_filter(res, 0, x, num2, array3, 0, num, psEnc.pitchEstimationLPCOrder); if (psEnc.indices.signalType != 0 && psEnc.first_frame_after_reset == 0) { int a2 = 4915; a2 = Inlines.silk_SMLABB(a2, -32, psEnc.pitchEstimationLPCOrder); a2 = Inlines.silk_SMLAWB(a2, -209714, psEnc.speech_activity_Q8); a2 = Inlines.silk_SMLABB(a2, -1228, Inlines.silk_RSHIFT(psEnc.prevSignalType, 1)); a2 = Inlines.silk_SMLAWB(a2, -1637, psEnc.input_tilt_Q15); a2 = Inlines.silk_SAT16(a2); BoxedValueShort boxedValueShort = new BoxedValueShort(psEnc.indices.lagIndex); BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(psEnc.indices.contourIndex); BoxedValueInt boxedValueInt = new BoxedValueInt(psEnc.LTPCorr_Q15); if (PitchAnalysisCore.silk_pitch_analysis_core(res, psEncCtrl.pitchL, boxedValueShort, boxedValueSbyte, boxedValueInt, psEnc.prevLag, psEnc.pitchEstimationThreshold_Q16, a2, psEnc.fs_kHz, psEnc.pitchEstimationComplexity, psEnc.nb_subfr) == 0) { psEnc.indices.signalType = 2; } else { psEnc.indices.signalType = 1; } psEnc.indices.lagIndex = boxedValueShort.Val; psEnc.indices.contourIndex = boxedValueSbyte.Val; psEnc.LTPCorr_Q15 = boxedValueInt.Val; } else { Arrays.MemSetInt(psEncCtrl.pitchL, 0, 4); psEnc.indices.lagIndex = 0; psEnc.indices.contourIndex = 0; psEnc.LTPCorr_Q15 = 0; } } } internal static class FindPredCoefs { internal static void silk_find_pred_coefs(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, short[] res_pitch, short[] x, int x_ptr, int condCoding) { int[] array = new int[4]; int[] array2 = new int[4]; int[] array3 = new int[4]; short[] array4 = new short[16]; int[] corr_rshifts = new int[4]; int num = 33554431; for (int i = 0; i < psEnc.nb_subfr; i++) { num = Inlines.silk_min(num, psEncCtrl.Gains_Q16[i]); } for (int i = 0; i < psEnc.nb_subfr; i++) { array[i] = Inlines.silk_DIV32_varQ(num, psEncCtrl.Gains_Q16[i], 14); array[i] = Inlines.silk_max(array[i], 363); int a = Inlines.silk_SMULWB(array[i], array[i]); array3[i] = Inlines.silk_RSHIFT(a, 1); array2[i] = Inlines.silk_DIV32(65536, array[i]); } short[] array5 = new short[psEnc.nb_subfr * psEnc.predictLPCOrder + psEnc.frame_length]; if (psEnc.indices.signalType == 2) { int[] array6 = new int[psEnc.nb_subfr * 5 * 5]; BoxedValueInt boxedValueInt = new BoxedValueInt(psEncCtrl.LTPredCodGain_Q7); FindLTP.silk_find_LTP(psEncCtrl.LTPCoef_Q14, array6, boxedValueInt, res_pitch, psEncCtrl.pitchL, array3, psEnc.subfr_length, psEnc.nb_subfr, psEnc.ltp_mem_length, corr_rshifts); psEncCtrl.LTPredCodGain_Q7 = boxedValueInt.Val; BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(psEnc.indices.PERIndex); BoxedValueInt boxedValueInt2 = new BoxedValueInt(psEnc.sum_log_gain_Q7); QuantizeLTPGains.silk_quant_LTP_gains(psEncCtrl.LTPCoef_Q14, psEnc.indices.LTPIndex, boxedValueSbyte, boxedValueInt2, array6, psEnc.mu_LTP_Q9, psEnc.LTPQuantLowComplexity, psEnc.nb_subfr); psEnc.indices.PERIndex = boxedValueSbyte.Val; psEnc.sum_log_gain_Q7 = boxedValueInt2.Val; LTPScaleControl.silk_LTP_scale_ctrl(psEnc, psEncCtrl, condCoding); LTPAnalysisFilter.silk_LTP_analysis_filter(array5, x, x_ptr - psEnc.predictLPCOrder, psEncCtrl.LTPCoef_Q14, psEncCtrl.pitchL, array, psEnc.subfr_length, psEnc.nb_subfr, psEnc.predictLPCOrder); } else { int num2 = x_ptr - psEnc.predictLPCOrder; int num3 = 0; for (int i = 0; i < psEnc.nb_subfr; i++) { Inlines.silk_scale_copy_vector16(array5, num3, x, num2, array[i], psEnc.subfr_length + psEnc.predictLPCOrder); num3 += psEnc.subfr_length + psEnc.predictLPCOrder; num2 += psEnc.subfr_length; } Arrays.MemSetShort(psEncCtrl.LTPCoef_Q14, 0, psEnc.nb_subfr * 5); psEncCtrl.LTPredCodGain_Q7 = 0; psEnc.sum_log_gain_Q7 = 0; } int minInvGain_Q; if (psEnc.first_frame_after_reset != 0) { minInvGain_Q = 10737418; } else { minInvGain_Q = Inlines.silk_log2lin(Inlines.silk_SMLAWB(2048, psEncCtrl.LTPredCodGain_Q7, 21845)); minInvGain_Q = Inlines.silk_DIV32_varQ(minInvGain_Q, Inlines.silk_SMULWW(10000, Inlines.silk_SMLAWB(65536, 196608, psEncCtrl.coding_quality_Q14)), 14); } FindLPC.silk_find_LPC(psEnc, array4, array5, minInvGain_Q); NLSF.silk_process_NLSFs(psEnc, psEncCtrl.PredCoef_Q12, array4, psEnc.prev_NLSFq_Q15); ResidualEnergy.silk_residual_energy(psEncCtrl.ResNrg, psEncCtrl.ResNrgQ, array5, psEncCtrl.PredCoef_Q12, array2, psEnc.subfr_length, psEnc.nb_subfr, psEnc.predictLPCOrder); Arrays.MemCopy(array4, 0, psEnc.prev_NLSFq_Q15, 0, 16); } } internal static class GainQuantization { private static readonly int OFFSET = 2090; private static readonly int SCALE_Q16 = 2251; private static readonly int INV_SCALE_Q16 = 1907825; internal static void silk_gains_quant(sbyte[] ind, int[] gain_Q16, BoxedValueSbyte prev_ind, int conditional, int nb_subfr) { for (int i = 0; i < nb_subfr; i++) { ind[i] = (sbyte)Inlines.silk_SMULWB(SCALE_Q16, Inlines.silk_lin2log(gain_Q16[i]) - OFFSET); if (ind[i] < prev_ind.Val) { ind[i]++; } ind[i] = (sbyte)Inlines.silk_LIMIT_int(ind[i], 0, 63); if (i == 0 && conditional == 0) { ind[i] = (sbyte)Inlines.silk_LIMIT_int(ind[i], prev_ind.Val + -4, 63); prev_ind.Val = ind[i]; } else { ind[i] -= prev_ind.Val; int num = 8 + prev_ind.Val; if (ind[i] > num) { ind[i] = (sbyte)(num + Inlines.silk_RSHIFT(ind[i] - num + 1, 1)); } ind[i] = (sbyte)Inlines.silk_LIMIT_int(ind[i], -4, 36); if (ind[i] > num) { prev_ind.Val += (sbyte)(Inlines.silk_LSHIFT(ind[i], 1) - num); } else { prev_ind.Val += ind[i]; } ind[i] -= -4; } gain_Q16[i] = Inlines.silk_log2lin(Inlines.silk_min_32(Inlines.silk_SMULWB(INV_SCALE_Q16, prev_ind.Val) + OFFSET, 3967)); } } internal static void silk_gains_dequant(int[] gain_Q16, sbyte[] ind, BoxedValueSbyte prev_ind, int conditional, int nb_subfr) { for (int i = 0; i < nb_subfr; i++) { if (i == 0 && conditional == 0) { prev_ind.Val = (sbyte)Inlines.silk_max_int(ind[i], prev_ind.Val - 16); } else { int num = ind[i] + -4; int num2 = 8 + prev_ind.Val; if (num > num2) { prev_ind.Val += (sbyte)(Inlines.silk_LSHIFT(num, 1) - num2); } else { prev_ind.Val += (sbyte)num; } } prev_ind.Val = (sbyte)Inlines.silk_LIMIT_int(prev_ind.Val, 0, 63); gain_Q16[i] = Inlines.silk_log2lin(Inlines.silk_min_32(Inlines.silk_SMULWB(INV_SCALE_Q16, prev_ind.Val) + OFFSET, 3967)); } } internal static int silk_gains_ID(sbyte[] ind, int nb_subfr) { int num = 0; for (int i = 0; i < nb_subfr; i++) { num = Inlines.silk_ADD_LSHIFT32(ind[i], num, 8); } return num; } } internal static class HPVariableCutoff { internal static void silk_HP_variable_cutoff(SilkChannelEncoder[] state_Fxx) { SilkChannelEncoder silkChannelEncoder = state_Fxx[0]; if (silkChannelEncoder.prevSignalType == 2) { int num = Inlines.silk_lin2log(Inlines.silk_DIV32_16(Inlines.silk_LSHIFT(Inlines.silk_MUL(silkChannelEncoder.fs_kHz, 1000), 16), silkChannelEncoder.prevLag)) - 2048; int num2 = silkChannelEncoder.input_quality_bands_Q15[0]; num = Inlines.silk_SMLAWB(num, Inlines.silk_SMULWB(Inlines.silk_LSHIFT(-num2, 2), num2), num - (Inlines.silk_lin2log(3932160) - 2048)); int num3 = num - Inlines.silk_RSHIFT(silkChannelEncoder.variable_HP_smth1_Q15, 8); if (num3 < 0) { num3 = Inlines.silk_MUL(num3, 3); } num3 = Inlines.silk_LIMIT_32(num3, -51, 51); silkChannelEncoder.variable_HP_smth1_Q15 = Inlines.silk_SMLAWB(silkChannelEncoder.variable_HP_smth1_Q15, Inlines.silk_SMULBB(silkChannelEncoder.speech_activity_Q8, num3), 6554); silkChannelEncoder.variable_HP_smth1_Q15 = Inlines.silk_LIMIT_32(silkChannelEncoder.variable_HP_smth1_Q15, Inlines.silk_LSHIFT(Inlines.silk_lin2log(60), 8), Inlines.silk_LSHIFT(Inlines.silk_lin2log(100), 8)); } } } internal static class K2A { internal static void silk_k2a(int[] A_Q24, short[] rc_Q15, int order) { int[] array = new int[16]; for (int i = 0; i < order; i++) { for (int j = 0; j < i; j++) { array[j] = A_Q24[j]; } for (int j = 0; j < i; j++) { A_Q24[j] = Inlines.silk_SMLAWB(A_Q24[j], Inlines.silk_LSHIFT(array[i - j - 1], 1), rc_Q15[i]); } A_Q24[i] = -Inlines.silk_LSHIFT(rc_Q15[i], 9); } } internal static void silk_k2a_Q16(int[] A_Q24, int[] rc_Q16, int order) { int[] array = new int[16]; for (int i = 0; i < order; i++) { for (int j = 0; j < i; j++) { array[j] = A_Q24[j]; } for (int j = 0; j < i; j++) { A_Q24[j] = Inlines.silk_SMLAWW(A_Q24[j], array[i - j - 1], rc_Q16[i]); } A_Q24[i] = -Inlines.silk_LSHIFT(rc_Q16[i], 8); } } } internal static class LinearAlgebra { internal static void silk_solve_LDL(int[] A, int A_ptr, int M, int[] b, int[] x_Q16) { int[] l_Q = new int[M * M]; int[] array = new int[16]; int[] inv_D = new int[32]; silk_LDL_factorize(A, A_ptr, M, l_Q, inv_D); silk_LS_SolveFirst(l_Q, M, b, array); silk_LS_divide_Q16(array, inv_D, M); silk_LS_SolveLast(l_Q, M, array, x_Q16); } private static void silk_LDL_factorize(int[] A, int A_ptr, int M, int[] L_Q16, int[] inv_D) { int[] array = new int[M]; int[] array2 = new int[M]; int num = 1; int num2 = Inlines.silk_max_32(Inlines.silk_SMMUL(Inlines.silk_ADD_SAT32(A[A_ptr], A[A_ptr + Inlines.silk_SMULBB(M, M) - 1]), 21475), 512); for (int i = 0; i < M; i++) { if (num != 1) { break; } num = 0; for (int j = 0; j < M; j++) { int[] array3 = L_Q16; int num3 = Inlines.MatrixGetPointer(j, 0, M); int num4 = 0; for (int k = 0; k < j; k++) { array[k] = Inlines.silk_SMULWW(array2[k], array3[num3 + k]); num4 = Inlines.silk_SMLAWW(num4, array[k], array3[num3 + k]); } num4 = Inlines.silk_SUB32(Inlines.MatrixGet(A, A_ptr, j, j, M), num4); if (num4 < num2) { num4 = Inlines.silk_SUB32(Inlines.silk_SMULBB(i + 1, num2), num4); for (int k = 0; k < M; k++) { Inlines.MatrixSet(A, A_ptr, k, k, M, Inlines.silk_ADD32(Inlines.MatrixGet(A, A_ptr, k, k, M), num4)); } num = 1; break; } array2[j] = num4; int num5 = Inlines.silk_INVERSE32_varQ(num4, 36); int b = Inlines.silk_LSHIFT(num5, 4); int num6 = Inlines.silk_SMULWW(Inlines.silk_SUB32(16777216, Inlines.silk_SMULWW(num4, b)), b); inv_D[j * 2] = num5; inv_D[j * 2 + 1] = num6; Inlines.MatrixSet(L_Q16, j, j, M, 65536); array3 = A; num3 = Inlines.MatrixGetPointer(j, 0, M) + A_ptr; int num7 = Inlines.MatrixGetPointer(j + 1, 0, M); for (int k = j + 1; k < M; k++) { num4 = 0; for (int l = 0; l < j; l++) { num4 = Inlines.silk_SMLAWW(num4, array[l], L_Q16[num7 + l]); } num4 = Inlines.silk_SUB32(array3[num3 + k], num4); Inlines.MatrixSet(L_Q16, k, j, M, Inlines.silk_ADD32(Inlines.silk_SMMUL(num4, num6), Inlines.silk_RSHIFT(Inlines.silk_SMULWW(num4, num5), 4))); num7 += M; } } } } private static void silk_LS_divide_Q16(int[] T, int[] inv_D, int M) { for (int i = 0; i < M; i++) { int b = inv_D[i * 2]; int b2 = inv_D[i * 2 + 1]; int a = T[i]; T[i] = Inlines.silk_ADD32(Inlines.silk_SMMUL(a, b2), Inlines.silk_RSHIFT(Inlines.silk_SMULWW(a, b), 4)); } } private static void silk_LS_SolveFirst(int[] L_Q16, int M, int[] b, int[] x_Q16) { for (int i = 0; i < M; i++) { int num = Inlines.MatrixGetPointer(i, 0, M); int num2 = 0; for (int j = 0; j < i; j++) { num2 = Inlines.silk_SMLAWW(num2, L_Q16[num + j], x_Q16[j]); } x_Q16[i] = Inlines.silk_SUB32(b[i], num2); } } private static void silk_LS_SolveLast(int[] L_Q16, int M, int[] b, int[] x_Q16) { for (int num = M - 1; num >= 0; num--) { int num2 = Inlines.MatrixGetPointer(0, num, M); int num3 = 0; for (int num4 = M - 1; num4 > num; num4--) { num3 = Inlines.silk_SMLAWW(num3, L_Q16[num2 + Inlines.silk_SMULBB(num4, M)], x_Q16[num4]); } x_Q16[num] = Inlines.silk_SUB32(b[num], num3); } } } internal static class LPCInversePredGain { private const float RC_THRESHOLD = 0.9999f; private const int QA = 24; private static readonly int A_LIMIT = 16773022; internal static int LPC_inverse_pred_gain_QA(int[][] A_QA, int order) { int[] array = A_QA[order & 1]; int a = 1073741824; int num2; int num3; for (int num = order - 1; num > 0; num--) { if (array[num] > A_LIMIT || array[num] < -A_LIMIT) { return 0; } num2 = -Inlines.silk_LSHIFT(array[num], 7); num3 = 1073741824 - Inlines.silk_SMMUL(num2, num2); int num4 = 32 - Inlines.silk_CLZ32(Inlines.silk_abs(num3)); int b = Inlines.silk_INVERSE32_varQ(num3, num4 + 30); a = Inlines.silk_LSHIFT(Inlines.silk_SMMUL(a, num3), 2); int[] array2 = array; array = A_QA[num & 1]; for (int i = 0; i < num; i++) { int a2 = array2[i] - Inlines.MUL32_FRAC_Q(array2[num - i - 1], num2, 31); array[i] = Inlines.MUL32_FRAC_Q(a2, b, num4); } } if (array[0] > A_LIMIT || array[0] < -A_LIMIT) { return 0; } num2 = -Inlines.silk_LSHIFT(array[0], 7); num3 = 1073741824 - Inlines.silk_SMMUL(num2, num2); return Inlines.silk_LSHIFT(Inlines.silk_SMMUL(a, num3), 2); } internal static int silk_LPC_inverse_pred_gain(short[] A_Q12, int order) { int[][] array = Arrays.InitTwoDimensionalArray(2, 16); int num = 0; int[] array2 = array[order & 1]; for (int i = 0; i < order; i++) { num += A_Q12[i]; array2[i] = Inlines.silk_LSHIFT32(A_Q12[i], 12); } if (num >= 4096) { return 0; } return LPC_inverse_pred_gain_QA(array, order); } internal static int silk_LPC_inverse_pred_gain_Q24(int[] A_Q24, int order) { int[][] array = Arrays.InitTwoDimensionalArray(2, 16); int[] array2 = array[order & 1]; for (int i = 0; i < order; i++) { array2[i] = Inlines.silk_RSHIFT32(A_Q24[i], 0); } return LPC_inverse_pred_gain_QA(array, order); } } internal static class LTPAnalysisFilter { internal static void silk_LTP_analysis_filter(short[] LTP_res, short[] x, int x_ptr, short[] LTPCoef_Q14, int[] pitchL, int[] invGains_Q16, int subfr_length, int nb_subfr, int pre_length) { short[] array = new short[5]; int num = x_ptr; int num2 = 0; for (int i = 0; i < nb_subfr; i++) { int num3 = num - pitchL[i]; array[0] = LTPCoef_Q14[i * 5]; array[1] = LTPCoef_Q14[i * 5 + 1]; array[2] = LTPCoef_Q14[i * 5 + 2]; array[3] = LTPCoef_Q14[i * 5 + 3]; array[4] = LTPCoef_Q14[i * 5 + 4]; for (int j = 0; j < subfr_length + pre_length; j++) { int num4 = num2 + j; LTP_res[num4] = x[num + j]; int a = Inlines.silk_SMULBB(x[num3 + 2], array[0]); a = Inlines.silk_SMLABB_ovflw(a, x[num3 + 1], array[1]); a = Inlines.silk_SMLABB_ovflw(a, x[num3], array[2]); a = Inlines.silk_SMLABB_ovflw(a, x[num3 - 1], array[3]); a = Inlines.silk_SMLABB_ovflw(a, x[num3 - 2], array[4]); a = Inlines.silk_RSHIFT_ROUND(a, 14); LTP_res[num4] = (short)Inlines.silk_SAT16(x[num + j] - a); LTP_res[num4] = (short)Inlines.silk_SMULWB(invGains_Q16[i], LTP_res[num4]); num3++; } num2 += subfr_length + pre_length; num += subfr_length; } } } internal static class LTPScaleControl { internal static void silk_LTP_scale_ctrl(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, int condCoding) { if (condCoding == 0) { int a = psEnc.PacketLoss_perc + psEnc.nFramesPerPacket; psEnc.indices.LTP_scaleIndex = (sbyte)Inlines.silk_LIMIT(Inlines.silk_SMULWB(Inlines.silk_SMULBB(a, psEncCtrl.LTPredCodGain_Q7), 51), 0, 2); } else { psEnc.indices.LTP_scaleIndex = 0; } psEncCtrl.LTP_scale_Q14 = Tables.silk_LTPScales_table_Q14[psEnc.indices.LTP_scaleIndex]; } } internal static class NLSF { private const int MAX_LPC_ORDER = 16; private const int MAX_STABILIZE_LOOPS = 20; private const int QA = 16; private const int BIN_DIV_STEPS_A2NLSF = 3; private const int MAX_ITERATIONS_A2NLSF = 30; private static readonly byte[] ordering16 = new byte[16] { 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 }; private static readonly byte[] ordering10 = new byte[10] { 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 }; internal static void silk_NLSF_VQ(int[] err_Q26, short[] in_Q15, byte[] pCB_Q8, int K, int LPC_order) { int num = 0; for (int i = 0; i < K; i++) { int num2 = 0; for (int j = 0; j < LPC_order; j += 2) { int num3 = Inlines.silk_SUB_LSHIFT32(in_Q15[j], pCB_Q8[num++], 7); int a = Inlines.silk_SMULBB(num3, num3); num3 = Inlines.silk_SUB_LSHIFT32(in_Q15[j + 1], pCB_Q8[num++], 7); a = Inlines.silk_SMLABB(a, num3, num3); num2 = Inlines.silk_ADD_RSHIFT32(num2, a, 4); } err_Q26[i] = num2; } } internal static void silk_NLSF_VQ_weights_laroia(Span pNLSFW_Q_OUT, Span pNLSF_Q15, int D) { int b = Inlines.silk_max_int(pNLSF_Q15[0], 1); b = Inlines.silk_DIV32(131072, b); int b2 = Inlines.silk_max_int(pNLSF_Q15[1] - pNLSF_Q15[0], 1); b2 = Inlines.silk_DIV32(131072, b2); pNLSFW_Q_OUT[0] = (short)Inlines.silk_min_int(b + b2, 32767); for (int i = 1; i < D - 1; i += 2) { b = Inlines.silk_max_int(pNLSF_Q15[i + 1] - pNLSF_Q15[i], 1); b = Inlines.silk_DIV32(131072, b); pNLSFW_Q_OUT[i] = (short)Inlines.silk_min_int(b + b2, 32767); b2 = Inlines.silk_max_int(pNLSF_Q15[i + 2] - pNLSF_Q15[i + 1], 1); b2 = Inlines.silk_DIV32(131072, b2); pNLSFW_Q_OUT[i + 1] = (short)Inlines.silk_min_int(b + b2, 32767); } b = Inlines.silk_max_int(32768 - pNLSF_Q15[D - 1], 1); b = Inlines.silk_DIV32(131072, b); pNLSFW_Q_OUT[D - 1] = (short)Inlines.silk_min_int(b + b2, 32767); } internal static void silk_NLSF_residual_dequant(Span x_Q10, Span indices, Span pred_coef_Q8, int quant_step_size_Q16, short order) { short num = 0; for (int num2 = order - 1; num2 >= 0; num2--) { int a = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(num, pred_coef_Q8[num2]), 8); num = Inlines.silk_LSHIFT16(indices[num2], 10); if (num > 0) { num = Inlines.silk_SUB16(num, 102); } else if (num < 0) { num = Inlines.silk_ADD16(num, 102); } num = (short)Inlines.silk_SMLAWB(a, num, quant_step_size_Q16); x_Q10[num2] = num; } } internal static void silk_NLSF_unpack(Span ec_ix, Span pred_Q8, NLSFCodebook psNLSF_CB, int CB1_index) { byte[] ec_sel = psNLSF_CB.ec_sel; int num = CB1_index * psNLSF_CB.order / 2; for (int i = 0; i < psNLSF_CB.order; i += 2) { byte b = ec_sel[num]; num++; ec_ix[i] = (short)Inlines.silk_SMULBB(Inlines.silk_RSHIFT(b, 1) & 7, 9); pred_Q8[i] = psNLSF_CB.pred_Q8[i + (b & 1) * (psNLSF_CB.order - 1)]; ec_ix[i + 1] = (short)Inlines.silk_SMULBB(Inlines.silk_RSHIFT(b, 5) & 7, 9); pred_Q8[i + 1] = psNLSF_CB.pred_Q8[i + (Inlines.silk_RSHIFT(b, 4) & 1) * (psNLSF_CB.order - 1) + 1]; } } internal static void silk_NLSF_stabilize(short[] NLSF_Q15, short[] NDeltaMin_Q15, int L) { int num = 0; int i; for (i = 0; i < 20; i++) { int num2 = NLSF_Q15[0] - NDeltaMin_Q15[0]; num = 0; int num3; for (int j = 1; j <= L - 1; j++) { num3 = NLSF_Q15[j] - (NLSF_Q15[j - 1] + NDeltaMin_Q15[j]); if (num3 < num2) { num2 = num3; num = j; } } num3 = 32768 - (NLSF_Q15[L - 1] + NDeltaMin_Q15[L]); if (num3 < num2) { num2 = num3; num = L; } if (num2 >= 0) { return; } if (num == 0) { NLSF_Q15[0] = NDeltaMin_Q15[0]; continue; } if (num == L) { NLSF_Q15[L - 1] = (short)(32768 - NDeltaMin_Q15[L]); continue; } int num4 = 0; for (int k = 0; k < num; k++) { num4 += NDeltaMin_Q15[k]; } num4 += Inlines.silk_RSHIFT(NDeltaMin_Q15[num], 1); int num5 = 32768; for (int k = L; k > num; k--) { num5 -= NDeltaMin_Q15[k]; } num5 -= Inlines.silk_RSHIFT(NDeltaMin_Q15[num], 1); short num6 = (short)Inlines.silk_LIMIT_32(Inlines.silk_RSHIFT_ROUND(NLSF_Q15[num - 1] + NLSF_Q15[num], 1), num4, num5); NLSF_Q15[num - 1] = (short)(num6 - Inlines.silk_RSHIFT(NDeltaMin_Q15[num], 1)); NLSF_Q15[num] = (short)(NLSF_Q15[num - 1] + NDeltaMin_Q15[num]); } if (i == 20) { Sort.silk_insertion_sort_increasing_all_values_int16(NLSF_Q15, L); NLSF_Q15[0] = (short)Inlines.silk_max_int(NLSF_Q15[0], NDeltaMin_Q15[0]); for (int j = 1; j < L; j++) { NLSF_Q15[j] = (short)Inlines.silk_max_int(NLSF_Q15[j], NLSF_Q15[j - 1] + NDeltaMin_Q15[j]); } NLSF_Q15[L - 1] = (short)Inlines.silk_min_int(NLSF_Q15[L - 1], 32768 - NDeltaMin_Q15[L]); for (int j = L - 2; j >= 0; j--) { NLSF_Q15[j] = (short)Inlines.silk_min_int(NLSF_Q15[j], NLSF_Q15[j + 1] - NDeltaMin_Q15[j + 1]); } } } internal static void silk_NLSF_decode(short[] pNLSF_Q15, sbyte[] NLSFIndices, NLSFCodebook psNLSF_CB) { Span span = stackalloc byte[16]; Span ec_ix = stackalloc short[16]; Span x_Q = stackalloc short[16]; Span pNLSFW_Q_OUT = stackalloc short[16]; byte[] cB1_NLSF_Q = psNLSF_CB.CB1_NLSF_Q8; int num = NLSFIndices[0] * psNLSF_CB.order; for (int i = 0; i < psNLSF_CB.order; i++) { pNLSF_Q15[i] = Inlines.silk_LSHIFT16(cB1_NLSF_Q[num + i], 7); } silk_NLSF_unpack(ec_ix, span, psNLSF_CB, NLSFIndices[0]); silk_NLSF_residual_dequant(x_Q, MemoryExtensions.AsSpan(NLSFIndices).Slice(1), span, psNLSF_CB.quantStepSize_Q16, psNLSF_CB.order); silk_NLSF_VQ_weights_laroia(pNLSFW_Q_OUT, pNLSF_Q15, psNLSF_CB.order); for (int i = 0; i < psNLSF_CB.order; i++) { int num2 = Inlines.silk_SQRT_APPROX(Inlines.silk_LSHIFT(pNLSFW_Q_OUT[i], 16)); int a = Inlines.silk_ADD32(pNLSF_Q15[i], Inlines.silk_DIV32_16(Inlines.silk_LSHIFT(x_Q[i], 14), (short)num2)); pNLSF_Q15[i] = (short)Inlines.silk_LIMIT(a, 0, 32767); } silk_NLSF_stabilize(pNLSF_Q15, psNLSF_CB.deltaMin_Q15, psNLSF_CB.order); } internal static int silk_NLSF_del_dec_quant(sbyte[] indices, Span x_Q10, Span w_Q5, Span pred_coef_Q8, Span ec_ix, byte[] ec_rates_Q5, int quant_step_size_Q16, short inv_quant_step_size_Q6, int mu_Q20, short order) { Span span = stackalloc int[4]; sbyte[][] array = new sbyte[4][]; int i; for (i = 0; i < 4; i++) { array[i] = new sbyte[16]; } Span span2 = stackalloc short[8]; Span span3 = stackalloc int[8]; Span span4 = stackalloc int[4]; Span span5 = stackalloc int[4]; Span span6 = stackalloc int[20]; Span span7 = stackalloc int[20]; for (i = -10; i <= 9; i++) { int num = Inlines.silk_LSHIFT(i, 10); int num2 = Inlines.silk_ADD16((short)num, 1024); if (i > 0) { num = Inlines.silk_SUB16((short)num, 102); num2 = Inlines.silk_SUB16((short)num2, 102); } else { switch (i) { case 0: num2 = Inlines.silk_SUB16((short)num2, 102); break; case -1: num = Inlines.silk_ADD16((short)num, 102); break; default: num = Inlines.silk_ADD16((short)num, 102); num2 = Inlines.silk_ADD16((short)num2, 102); break; } } span6[i + 10] = Inlines.silk_SMULWB(num, quant_step_size_Q16); span7[i + 10] = Inlines.silk_SMULWB(num2, quant_step_size_Q16); } int num3 = 1; span3[0] = 0; span2[0] = 0; i = order - 1; int a2; while (true) { int a = Inlines.silk_LSHIFT(pred_coef_Q8[i], 8); int num4 = x_Q10[i]; for (int j = 0; j < num3; j++) { int num5 = Inlines.silk_SMULWB(a, span2[j]); int b = Inlines.silk_SUB16((short)num4, (short)num5); a2 = Inlines.silk_SMULWB(inv_quant_step_size_Q6, b); a2 = Inlines.silk_LIMIT(a2, -10, 9); array[j][i] = (sbyte)a2; int num6 = ec_ix[i] + a2; int num = span6[a2 + 10]; int num2 = span7[a2 + 10]; num = Inlines.silk_ADD16((short)num, (short)num5); num2 = Inlines.silk_ADD16((short)num2, (short)num5); span2[j] = (short)num; span2[j + num3] = (short)num2; int num7; int c; if (a2 + 1 >= 4) { if (a2 + 1 == 4) { num7 = ec_rates_Q5[num6 + 4]; c = 280; } else { num7 = Inlines.silk_SMLABB(108, 43, a2); c = Inlines.silk_ADD16((short)num7, 43); } } else if (a2 <= -4) { if (a2 == -4) { num7 = 280; c = ec_rates_Q5[num6 + 1 + 4]; } else { num7 = Inlines.silk_SMLABB(108, -43, a2); c = Inlines.silk_SUB16((short)num7, 43); } } else { num7 = ec_rates_Q5[num6 + 4]; c = ec_rates_Q5[num6 + 1 + 4]; } int a3 = span3[j]; int num8 = Inlines.silk_SUB16((short)num4, (short)num); span3[j] = Inlines.silk_SMLABB(Inlines.silk_MLA(a3, Inlines.silk_SMULBB(num8, num8), w_Q5[i]), mu_Q20, num7); num8 = Inlines.silk_SUB16((short)num4, (short)num2); span3[j + num3] = Inlines.silk_SMLABB(Inlines.silk_MLA(a3, Inlines.silk_SMULBB(num8, num8), w_Q5[i]), mu_Q20, c); } if (num3 <= 2) { for (int j = 0; j < num3; j++) { array[j + num3][i] = (sbyte)(array[j][i] + 1); } num3 = Inlines.silk_LSHIFT(num3, 1); for (int j = num3; j < 4; j++) { array[j][i] = array[j - num3][i]; } } else { if (i <= 0) { break; } for (int j = 0; j < 4; j++) { if (span3[j] > span3[j + 4]) { span5[j] = span3[j]; span4[j] = span3[j + 4]; span3[j] = span4[j]; span3[j + 4] = span5[j]; int num = span2[j]; span2[j] = span2[j + 4]; span2[j + 4] = (short)num; span[j] = j + 4; } else { span4[j] = span3[j]; span5[j] = span3[j + 4]; span[j] = j; } } while (true) { int num9 = int.MaxValue; int num10 = 0; int num11 = 0; int num12 = 0; for (int j = 0; j < 4; j++) { if (num9 > span5[j]) { num9 = span5[j]; num11 = j; } if (num10 < span4[j]) { num10 = span4[j]; num12 = j; } } if (num9 >= num10) { break; } span[num12] = span[num11] ^ 4; span3[num12] = span3[num11 + 4]; span2[num12] = span2[num11 + 4]; span4[num12] = 0; span5[num11] = int.MaxValue; Buffer.BlockCopy(array[num11], 0, array[num12], 0, order); } for (int j = 0; j < 4; j++) { sbyte b2 = (sbyte)Inlines.silk_RSHIFT(span[j], 2); array[j][i] += b2; } } i--; } a2 = 0; int num13 = int.MaxValue; for (int j = 0; j < 8; j++) { if (num13 > span3[j]) { num13 = span3[j]; a2 = j; } } for (int j = 0; j < order; j++) { indices[j] = array[a2 & 3][j]; } indices[0] = (sbyte)(indices[0] + Inlines.silk_RSHIFT(a2, 2)); return num13; } internal static int silk_NLSF_encode(sbyte[] NLSFIndices, short[] pNLSF_Q15, NLSFCodebook psNLSF_CB, short[] pW_QW, int NLSF_mu_Q20, int nSurvivors, int signalType) { Span span = stackalloc short[16]; Span x_Q = stackalloc short[16]; Span pNLSF_Q16 = stackalloc short[16]; Span pNLSFW_Q_OUT = stackalloc short[16]; Span w_Q = stackalloc short[16]; Span span2 = stackalloc byte[16]; Span ec_ix = stackalloc short[16]; byte[] cB1_NLSF_Q = psNLSF_CB.CB1_NLSF_Q8; silk_NLSF_stabilize(pNLSF_Q15, psNLSF_CB.deltaMin_Q15, psNLSF_CB.order); int[] array = new int[psNLSF_CB.nVectors]; silk_NLSF_VQ(array, pNLSF_Q15, psNLSF_CB.CB1_NLSF_Q8, psNLSF_CB.nVectors, psNLSF_CB.order); int[] array2 = new int[nSurvivors]; Sort.silk_insertion_sort_increasing(array, array2, psNLSF_CB.nVectors, nSurvivors); int[] array3 = new int[nSurvivors]; sbyte[][] array4 = Arrays.InitTwoDimensionalArray(nSurvivors, 16); for (int i = 0; i < nSurvivors; i++) { int num = array2[i]; int num2 = num * psNLSF_CB.order; for (int j = 0; j < psNLSF_CB.order; j++) { pNLSF_Q16[j] = Inlines.silk_LSHIFT16(cB1_NLSF_Q[num2 + j], 7); span[j] = (short)(pNLSF_Q15[j] - pNLSF_Q16[j]); } silk_NLSF_VQ_weights_laroia(pNLSFW_Q_OUT, pNLSF_Q16, psNLSF_CB.order); for (int j = 0; j < psNLSF_CB.order; j++) { int b = Inlines.silk_SQRT_APPROX(Inlines.silk_LSHIFT(pNLSFW_Q_OUT[j], 16)); x_Q[j] = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(span[j], b), 14); } for (int j = 0; j < psNLSF_CB.order; j++) { w_Q[j] = (short)Inlines.silk_DIV32_16(Inlines.silk_LSHIFT(pW_QW[j], 5), pNLSFW_Q_OUT[j]); } silk_NLSF_unpack(ec_ix, span2, psNLSF_CB, num); array3[i] = silk_NLSF_del_dec_quant(array4[i], x_Q, w_Q, span2, ec_ix, psNLSF_CB.ec_Rates_Q5, psNLSF_CB.quantStepSize_Q16, psNLSF_CB.invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB.order); int num3 = (signalType >> 1) * psNLSF_CB.nVectors; int inLin = ((num != 0) ? (psNLSF_CB.CB1_iCDF[num3 + num - 1] - psNLSF_CB.CB1_iCDF[num3 + num]) : (256 - psNLSF_CB.CB1_iCDF[num3 + num])); int b2 = 1024 - Inlines.silk_lin2log(inLin); array3[i] = Inlines.silk_SMLABB(array3[i], b2, Inlines.silk_RSHIFT(NLSF_mu_Q20, 2)); } int[] array5 = new int[1]; Sort.silk_insertion_sort_increasing(array3, array5, nSurvivors, 1); NLSFIndices[0] = (sbyte)array2[array5[0]]; Arrays.MemCopy(array4[array5[0]], 0, NLSFIndices, 1, psNLSF_CB.order); silk_NLSF_decode(pNLSF_Q15, NLSFIndices, psNLSF_CB); return array3[0]; } internal static void silk_NLSF2A_find_poly(int[] o, Span cLSF, int dd) { o[0] = Inlines.silk_LSHIFT(1, 16); o[1] = -cLSF[0]; for (int i = 1; i < dd; i++) { int num = cLSF[2 * i]; o[i + 1] = Inlines.silk_LSHIFT(o[i - 1], 1) - (int)Inlines.silk_RSHIFT_ROUND64(Inlines.silk_SMULL(num, o[i]), 16); for (int num2 = i; num2 > 1; num2--) { o[num2] += o[num2 - 2] - (int)Inlines.silk_RSHIFT_ROUND64(Inlines.silk_SMULL(num, o[num2 - 1]), 16); } o[1] -= num; } } internal static void silk_NLSF2A(short[] a_Q12, short[] NLSF, int d) { int[] array = new int[d]; int[] array2 = new int[d / 2 + 1]; int[] array3 = new int[d / 2 + 1]; int[] array4 = new int[d]; int num = 0; byte[] array5 = ((d == 16) ? ordering16 : ordering10); for (int i = 0; i < d; i++) { int num2 = Inlines.silk_RSHIFT(NLSF[i], 8); int b = NLSF[i] - Inlines.silk_LSHIFT(num2, 8); int num3 = Tables.silk_LSFCosTab_Q12[num2]; int a = Tables.silk_LSFCosTab_Q12[num2 + 1] - num3; array[array5[i]] = Inlines.silk_RSHIFT_ROUND(Inlines.silk_LSHIFT(num3, 8) + Inlines.silk_MUL(a, b), 4); } int num4 = Inlines.silk_RSHIFT(d, 1); silk_NLSF2A_find_poly(array2, MemoryExtensions.AsSpan(array), num4); silk_NLSF2A_find_poly(array3, MemoryExtensions.AsSpan(array).Slice(1), num4); for (int i = 0; i < num4; i++) { int num5 = array2[i + 1] + array2[i]; int num6 = array3[i + 1] - array3[i]; array4[i] = -num6 - num5; array4[d - i - 1] = num6 - num5; } int j; for (j = 0; j < 10; j++) { int num7 = 0; for (int i = 0; i < d; i++) { int num8 = Inlines.silk_abs(array4[i]); if (num8 > num7) { num7 = num8; num = i; } } num7 = Inlines.silk_RSHIFT_ROUND(num7, 5); if (num7 <= 32767) { break; } num7 = Inlines.silk_min(num7, 163838); int chirp_Q = 65470 - Inlines.silk_DIV32(Inlines.silk_LSHIFT(num7 - 32767, 14), Inlines.silk_RSHIFT32(Inlines.silk_MUL(num7, num + 1), 2)); Filters.silk_bwexpander_32(array4, d, chirp_Q); } if (j == 10) { for (int i = 0; i < d; i++) { a_Q12[i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(array4[i], 5)); array4[i] = Inlines.silk_LSHIFT(a_Q12[i], 5); } } else { for (int i = 0; i < d; i++) { a_Q12[i] = (short)Inlines.silk_RSHIFT_ROUND(array4[i], 5); } } for (j = 0; j < 16; j++) { if (Filters.silk_LPC_inverse_pred_gain(a_Q12, d) >= 107374) { break; } Filters.silk_bwexpander_32(array4, d, 65536 - Inlines.silk_LSHIFT(2, j)); for (int i = 0; i < d; i++) { a_Q12[i] = (short)Inlines.silk_RSHIFT_ROUND(array4[i], 5); } } } internal static void silk_A2NLSF_trans_poly(int[] p, int dd) { for (int i = 2; i <= dd; i++) { for (int num = dd; num > i; num--) { p[num - 2] -= p[num]; } p[i - 2] -= Inlines.silk_LSHIFT(p[i], 1); } } internal static int silk_A2NLSF_eval_poly(int[] p, int x, int dd) { int num = p[dd]; int c = Inlines.silk_LSHIFT(x, 4); if (8 == dd) { num = Inlines.silk_SMLAWW(p[7], num, c); num = Inlines.silk_SMLAWW(p[6], num, c); num = Inlines.silk_SMLAWW(p[5], num, c); num = Inlines.silk_SMLAWW(p[4], num, c); num = Inlines.silk_SMLAWW(p[3], num, c); num = Inlines.silk_SMLAWW(p[2], num, c); num = Inlines.silk_SMLAWW(p[1], num, c); num = Inlines.silk_SMLAWW(p[0], num, c); } else { for (int num2 = dd - 1; num2 >= 0; num2--) { num = Inlines.silk_SMLAWW(p[num2], num, c); } } return num; } internal static void silk_A2NLSF_init(int[] a_Q16, int[] P, int[] Q, int dd) { P[dd] = Inlines.silk_LSHIFT(1, 16); Q[dd] = Inlines.silk_LSHIFT(1, 16); for (int i = 0; i < dd; i++) { P[i] = -a_Q16[dd - i - 1] - a_Q16[dd + i]; Q[i] = -a_Q16[dd - i - 1] + a_Q16[dd + i]; } for (int i = dd; i > 0; i--) { P[i - 1] -= P[i]; Q[i - 1] += Q[i]; } silk_A2NLSF_trans_poly(P, dd); silk_A2NLSF_trans_poly(Q, dd); } internal static void silk_A2NLSF(short[] NLSF, int[] a_Q16, int d) { int[] array = new int[9]; int[] array2 = new int[9]; int[][] array3 = new int[2][] { array, array2 }; int dd = Inlines.silk_RSHIFT(d, 1); silk_A2NLSF_init(a_Q16, array, array2, dd); int[] p = array; int num = Tables.silk_LSFCosTab_Q12[0]; int num2 = silk_A2NLSF_eval_poly(p, num, dd); int num3; if (num2 < 0) { NLSF[0] = 0; p = array2; num2 = silk_A2NLSF_eval_poly(p, num, dd); num3 = 1; } else { num3 = 0; } int num4 = 1; int num5 = 0; int num6 = 0; while (true) { int num7 = Tables.silk_LSFCosTab_Q12[num4]; int num8 = silk_A2NLSF_eval_poly(p, num7, dd); if ((num2 <= 0 && num8 >= num6) || (num2 >= 0 && num8 <= -num6)) { num6 = ((num8 == 0) ? 1 : 0); int num9 = -256; for (int i = 0; i < 3; i++) { int num10 = Inlines.silk_RSHIFT_ROUND(num + num7, 1); int num11 = silk_A2NLSF_eval_poly(p, num10, dd); if ((num2 <= 0 && num11 >= 0) || (num2 >= 0 && num11 <= 0)) { num7 = num10; num8 = num11; } else { num = num10; num2 = num11; num9 = Inlines.silk_ADD_RSHIFT(num9, 128, i); } } if (Inlines.silk_abs(num2) < 65536) { int num12 = num2 - num8; int a = Inlines.silk_LSHIFT(num2, 5) + Inlines.silk_RSHIFT(num12, 1); if (num12 != 0) { num9 += Inlines.silk_DIV32(a, num12); } } else { num9 += Inlines.silk_DIV32(num2, Inlines.silk_RSHIFT(num2 - num8, 5)); } NLSF[num3] = (short)Inlines.silk_min_32(Inlines.silk_LSHIFT(num4, 8) + num9, 32767); num3++; if (num3 < d) { p = array3[num3 & 1]; num = Tables.silk_LSFCosTab_Q12[num4 - 1]; num2 = Inlines.silk_LSHIFT(1 - (num3 & 2), 12); continue; } break; } num4++; num = num7; num2 = num8; num6 = 0; if (num4 <= 128) { continue; } num5++; if (num5 > 30) { NLSF[0] = (short)Inlines.silk_DIV32_16(32768, (short)(d + 1)); for (num4 = 1; num4 < d; num4++) { NLSF[num4] = (short)Inlines.silk_SMULBB(num4 + 1, NLSF[0]); } break; } Filters.silk_bwexpander_32(a_Q16, d, 65536 - Inlines.silk_SMULBB(10 + num5, num5)); silk_A2NLSF_init(a_Q16, array, array2, dd); p = array; num = Tables.silk_LSFCosTab_Q12[0]; num2 = silk_A2NLSF_eval_poly(p, num, dd); if (num2 < 0) { NLSF[0] = 0; p = array2; num2 = silk_A2NLSF_eval_poly(p, num, dd); num3 = 1; } else { num3 = 0; } num4 = 1; } } internal static void silk_process_NLSFs(SilkChannelEncoder psEncC, short[][] PredCoef_Q12, short[] pNLSF_Q15, short[] prev_NLSFq_Q15) { short[] array = new short[16]; short[] array2 = new short[16]; short[] array3 = new short[16]; int num = Inlines.silk_SMLAWB(3146, -268434, psEncC.speech_activity_Q8); if (psEncC.nb_subfr == 2) { num = Inlines.silk_ADD_RSHIFT(num, num, 1); } silk_NLSF_VQ_weights_laroia(array2, pNLSF_Q15, psEncC.predictLPCOrder); bool flag = psEncC.useInterpolatedNLSFs == 1 && psEncC.indices.NLSFInterpCoef_Q2 < 4; if (flag) { Inlines.silk_interpolate(array, prev_NLSFq_Q15, pNLSF_Q15, psEncC.indices.NLSFInterpCoef_Q2, psEncC.predictLPCOrder); silk_NLSF_VQ_weights_laroia(array3, array, psEncC.predictLPCOrder); int c = Inlines.silk_LSHIFT(Inlines.silk_SMULBB(psEncC.indices.NLSFInterpCoef_Q2, psEncC.indices.NLSFInterpCoef_Q2), 11); for (int i = 0; i < psEncC.predictLPCOrder; i++) { array2[i] = (short)Inlines.silk_SMLAWB(Inlines.silk_RSHIFT(array2[i], 1), array3[i], c); } } silk_NLSF_encode(psEncC.indices.NLSFIndices, pNLSF_Q15, psEncC.psNLSF_CB, array2, num, psEncC.NLSF_MSVQ_Survivors, psEncC.indices.signalType); silk_NLSF2A(PredCoef_Q12[1], pNLSF_Q15, psEncC.predictLPCOrder); if (flag) { Inlines.silk_interpolate(array, prev_NLSFq_Q15, pNLSF_Q15, psEncC.indices.NLSFInterpCoef_Q2, psEncC.predictLPCOrder); silk_NLSF2A(PredCoef_Q12[0], array, psEncC.predictLPCOrder); } else { Arrays.MemCopy(PredCoef_Q12[1], 0, PredCoef_Q12[0], 0, psEncC.predictLPCOrder); } } } internal static class NoiseShapeAnalysis { internal static int warped_gain(int[] coefs_Q24, int lambda_Q16, int order) { lambda_Q16 = -lambda_Q16; int b = coefs_Q24[order - 1]; for (int num = order - 2; num >= 0; num--) { b = Inlines.silk_SMLAWB(coefs_Q24[num], b, lambda_Q16); } b = Inlines.silk_SMLAWB(16777216, b, -lambda_Q16); return Inlines.silk_INVERSE32_varQ(b, 40); } internal static void limit_warped_coefs(int[] coefs_syn_Q24, int[] coefs_ana_Q24, int lambda_Q16, int limit_Q24, int order) { int num = 0; lambda_Q16 = -lambda_Q16; for (int num2 = order - 1; num2 > 0; num2--) { coefs_syn_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_syn_Q24[num2 - 1], coefs_syn_Q24[num2], lambda_Q16); coefs_ana_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_ana_Q24[num2 - 1], coefs_ana_Q24[num2], lambda_Q16); } lambda_Q16 = -lambda_Q16; int a = Inlines.silk_SMLAWB(65536, -lambda_Q16, lambda_Q16); int b = Inlines.silk_SMLAWB(16777216, coefs_syn_Q24[0], lambda_Q16); int num3 = Inlines.silk_DIV32_varQ(a, b, 24); b = Inlines.silk_SMLAWB(16777216, coefs_ana_Q24[0], lambda_Q16); int num4 = Inlines.silk_DIV32_varQ(a, b, 24); for (int num2 = 0; num2 < order; num2++) { coefs_syn_Q24[num2] = Inlines.silk_SMULWW(num3, coefs_syn_Q24[num2]); coefs_ana_Q24[num2] = Inlines.silk_SMULWW(num4, coefs_ana_Q24[num2]); } for (int i = 0; i < 10; i++) { int num5 = -1; for (int num2 = 0; num2 < order; num2++) { int num6 = Inlines.silk_max(Inlines.silk_abs_int32(coefs_syn_Q24[num2]), Inlines.silk_abs_int32(coefs_ana_Q24[num2])); if (num6 > num5) { num5 = num6; num = num2; } } if (num5 <= limit_Q24) { break; } for (int num2 = 1; num2 < order; num2++) { coefs_syn_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_syn_Q24[num2 - 1], coefs_syn_Q24[num2], lambda_Q16); coefs_ana_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_ana_Q24[num2 - 1], coefs_ana_Q24[num2], lambda_Q16); } num3 = Inlines.silk_INVERSE32_varQ(num3, 32); num4 = Inlines.silk_INVERSE32_varQ(num4, 32); for (int num2 = 0; num2 < order; num2++) { coefs_syn_Q24[num2] = Inlines.silk_SMULWW(num3, coefs_syn_Q24[num2]); coefs_ana_Q24[num2] = Inlines.silk_SMULWW(num4, coefs_ana_Q24[num2]); } int chirp_Q = 64881 - Inlines.silk_DIV32_varQ(Inlines.silk_SMULWB(num5 - limit_Q24, Inlines.silk_SMLABB(819, 102, i)), Inlines.silk_MUL(num5, num + 1), 22); BWExpander.silk_bwexpander_32(coefs_syn_Q24, order, chirp_Q); BWExpander.silk_bwexpander_32(coefs_ana_Q24, order, chirp_Q); lambda_Q16 = -lambda_Q16; for (int num2 = order - 1; num2 > 0; num2--) { coefs_syn_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_syn_Q24[num2 - 1], coefs_syn_Q24[num2], lambda_Q16); coefs_ana_Q24[num2 - 1] = Inlines.silk_SMLAWB(coefs_ana_Q24[num2 - 1], coefs_ana_Q24[num2], lambda_Q16); } lambda_Q16 = -lambda_Q16; int a2 = Inlines.silk_SMLAWB(65536, -lambda_Q16, lambda_Q16); b = Inlines.silk_SMLAWB(16777216, coefs_syn_Q24[0], lambda_Q16); num3 = Inlines.silk_DIV32_varQ(a2, b, 24); b = Inlines.silk_SMLAWB(16777216, coefs_ana_Q24[0], lambda_Q16); num4 = Inlines.silk_DIV32_varQ(a2, b, 24); for (int num2 = 0; num2 < order; num2++) { coefs_syn_Q24[num2] = Inlines.silk_SMULWW(num3, coefs_syn_Q24[num2]); coefs_ana_Q24[num2] = Inlines.silk_SMULWW(num4, coefs_ana_Q24[num2]); } } } internal static void silk_noise_shape_analysis(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, short[] pitch_res, int pitch_res_ptr, short[] x, int x_ptr) { SilkShapeState sShape = psEnc.sShape; int shift = 0; int[] array = new int[17]; int[] rc_Q = new int[16]; int[] array2 = new int[16]; int[] array3 = new int[16]; int num = x_ptr - psEnc.la_shape; int num2 = psEnc.SNR_dB_Q7; psEncCtrl.input_quality_Q14 = Inlines.silk_RSHIFT(psEnc.input_quality_bands_Q15[0] + psEnc.input_quality_bands_Q15[1], 2); psEncCtrl.coding_quality_Q14 = Inlines.silk_RSHIFT(Sigmoid.silk_sigm_Q15(Inlines.silk_RSHIFT_ROUND(num2 - 2560, 4)), 1); if (psEnc.useCBR == 0) { int num3 = 256 - psEnc.speech_activity_Q8; num3 = Inlines.silk_SMULWB(Inlines.silk_LSHIFT(num3, 8), num3); num2 = Inlines.silk_SMLAWB(num2, Inlines.silk_SMULBB(-8, num3), Inlines.silk_SMULWB(16384 + psEncCtrl.input_quality_Q14, psEncCtrl.coding_quality_Q14)); } num2 = ((psEnc.indices.signalType != 2) ? Inlines.silk_SMLAWB(num2, Inlines.silk_SMLAWB(3072, -104858, psEnc.SNR_dB_Q7), 16384 - psEncCtrl.input_quality_Q14) : Inlines.silk_SMLAWB(num2, 512, psEnc.LTPCorr_Q15)); if (psEnc.indices.signalType == 2) { psEnc.indices.quantOffsetType = 0; psEncCtrl.sparseness_Q8 = 0; } else { int num4 = Inlines.silk_LSHIFT(psEnc.fs_kHz, 1); int num5 = 0; int num6 = 0; int num7 = pitch_res_ptr; for (int i = 0; i < Inlines.silk_SMULBB(5, psEnc.nb_subfr) / 2; i++) { SumSqrShift.silk_sum_sqr_shift(out var energy, out shift, pitch_res, num7, num4); energy += Inlines.silk_RSHIFT(num4, shift); int num8 = Inlines.silk_lin2log(energy); if (i > 0) { num5 += Inlines.silk_abs(num8 - num6); } num6 = num8; num7 += num4; } psEncCtrl.sparseness_Q8 = Inlines.silk_RSHIFT(Sigmoid.silk_sigm_Q15(Inlines.silk_SMULWB(num5 - 640, 6554)), 7); if (psEncCtrl.sparseness_Q8 > 192) { psEnc.indices.quantOffsetType = 0; } else { psEnc.indices.quantOffsetType = 1; } num2 = Inlines.silk_SMLAWB(num2, 65536, psEncCtrl.sparseness_Q8 - 128); } int num9 = Inlines.silk_SMULWB(psEncCtrl.predGain_Q16, 66); int a2; int a = (a2 = Inlines.silk_DIV32_varQ(62259, Inlines.silk_SMLAWW(65536, num9, num9), 16)); int b = Inlines.silk_SMULWB(65536 - Inlines.silk_SMULBB(3, psEncCtrl.coding_quality_Q14), 655); a = Inlines.silk_SUB32(a, b); a2 = Inlines.silk_ADD32(a2, b); a = Inlines.silk_DIV32_16(Inlines.silk_LSHIFT(a, 14), Inlines.silk_RSHIFT(a2, 2)); int num10 = ((psEnc.warping_Q16 > 0) ? Inlines.silk_SMLAWB(psEnc.warping_Q16, psEncCtrl.coding_quality_Q14, 2621) : 0); short[] array4 = new short[psEnc.shapeWinLength]; int b2; for (int i = 0; i < psEnc.nb_subfr; i++) { int num11 = psEnc.fs_kHz * 3; int num12 = Inlines.silk_RSHIFT(psEnc.shapeWinLength - num11, 1); ApplySineWindow.silk_apply_sine_window(array4, 0, x, num, 1, num12); int num13 = num12; Arrays.MemCopy(x, num + num13, array4, num13, num11); num13 += num11; ApplySineWindow.silk_apply_sine_window(array4, num13, x, num + num13, 2, num12); num += psEnc.subfr_length; if (psEnc.warping_Q16 > 0) { Autocorrelation.silk_warped_autocorrelation(array, out shift, array4, num10, psEnc.shapeWinLength, psEnc.shapingLPCOrder); } else { Autocorrelation.silk_autocorr(array, out shift, array4, psEnc.shapeWinLength, psEnc.shapingLPCOrder + 1); } array[0] = Inlines.silk_ADD32(array[0], Inlines.silk_max_32(Inlines.silk_SMULWB(Inlines.silk_RSHIFT(array[0], 4), 52), 1)); int energy = Schur.silk_schur64(rc_Q, array, psEnc.shapingLPCOrder); K2A.silk_k2a_Q16(array3, rc_Q, psEnc.shapingLPCOrder); int num14 = -shift; if ((num14 & 1) != 0) { num14--; energy >>= 1; } int a3 = Inlines.silk_SQRT_APPROX(energy); num14 >>= 1; psEncCtrl.Gains_Q16[i] = Inlines.silk_LSHIFT_SAT32(a3, 16 - num14); if (psEnc.warping_Q16 > 0) { b2 = warped_gain(array3, num10, psEnc.shapingLPCOrder); if (Inlines.silk_SMULWW(Inlines.silk_RSHIFT_ROUND(psEncCtrl.Gains_Q16[i], 1), b2) >= 1073741823) { psEncCtrl.Gains_Q16[i] = int.MaxValue; } else { psEncCtrl.Gains_Q16[i] = Inlines.silk_SMULWW(psEncCtrl.Gains_Q16[i], b2); } } BWExpander.silk_bwexpander_32(array3, psEnc.shapingLPCOrder, a2); Arrays.MemCopy(array3, 0, array2, 0, psEnc.shapingLPCOrder); BWExpander.silk_bwexpander_32(array2, psEnc.shapingLPCOrder, a); int a4 = LPCInversePredGain.silk_LPC_inverse_pred_gain_Q24(array3, psEnc.shapingLPCOrder); energy = LPCInversePredGain.silk_LPC_inverse_pred_gain_Q24(array2, psEnc.shapingLPCOrder); a4 = Inlines.silk_LSHIFT32(Inlines.silk_SMULWB(a4, 22938), 1); psEncCtrl.GainsPre_Q14[i] = 4915 + Inlines.silk_DIV32_varQ(a4, energy, 14); limit_warped_coefs(array3, array2, num10, 67092088, psEnc.shapingLPCOrder); for (int j = 0; j < psEnc.shapingLPCOrder; j++) { psEncCtrl.AR1_Q13[i * 16 + j] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(array2[j], 11)); psEncCtrl.AR2_Q13[i * 16 + j] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(array3[j], 11)); } } b2 = Inlines.silk_log2lin(-Inlines.silk_SMLAWB(-2048, num2, 10486)); int b3 = Inlines.silk_log2lin(Inlines.silk_SMLAWB(2048, 256, 10486)); for (int i = 0; i < psEnc.nb_subfr; i++) { psEncCtrl.Gains_Q16[i] = Inlines.silk_SMULWW(psEncCtrl.Gains_Q16[i], b2); psEncCtrl.Gains_Q16[i] = Inlines.silk_ADD_POS_SAT32(psEncCtrl.Gains_Q16[i], b3); } b2 = 65536 + Inlines.silk_RSHIFT_ROUND(Inlines.silk_MLA(3355443, psEncCtrl.coding_quality_Q14, 410), 10); for (int i = 0; i < psEnc.nb_subfr; i++) { psEncCtrl.GainsPre_Q14[i] = Inlines.silk_SMULWB(b2, psEncCtrl.GainsPre_Q14[i]); } num9 = Inlines.silk_MUL(64, Inlines.silk_SMLAWB(4096, 4096, psEnc.input_quality_bands_Q15[0] - 32768)); num9 = Inlines.silk_RSHIFT(Inlines.silk_MUL(num9, psEnc.speech_activity_Q8), 8); int num17; if (psEnc.indices.signalType == 2) { int num15 = Inlines.silk_DIV32_16(3277, psEnc.fs_kHz); for (int i = 0; i < psEnc.nb_subfr; i++) { int num16 = num15 + Inlines.silk_DIV32_16(49152, psEncCtrl.pitchL[i]); psEncCtrl.LF_shp_Q14[i] = Inlines.silk_LSHIFT(16384 - num16 - Inlines.silk_SMULWB(num9, num16), 16); psEncCtrl.LF_shp_Q14[i] |= (num16 - 16384) & 0xFFFF; } num17 = -16384 - Inlines.silk_SMULWB(49152, Inlines.silk_SMULWB(5872026, psEnc.speech_activity_Q8)); } else { int num16 = Inlines.silk_DIV32_16(21299, psEnc.fs_kHz); psEncCtrl.LF_shp_Q14[0] = Inlines.silk_LSHIFT(16384 - num16 - Inlines.silk_SMULWB(num9, Inlines.silk_SMULWB(39322, num16)), 16); psEncCtrl.LF_shp_Q14[0] |= (num16 - 16384) & 0xFFFF; for (int i = 1; i < psEnc.nb_subfr; i++) { psEncCtrl.LF_shp_Q14[i] = psEncCtrl.LF_shp_Q14[0]; } num17 = -16384; } int a5 = Inlines.silk_SMULWB(Inlines.silk_SMULWB(131072 - Inlines.silk_LSHIFT(psEncCtrl.coding_quality_Q14, 3), psEnc.LTPCorr_Q15), 6554); a5 = Inlines.silk_SMLAWB(a5, 65536 - Inlines.silk_LSHIFT(psEncCtrl.input_quality_Q14, 2), 6554); int a6; if (psEnc.indices.signalType == 2) { a6 = Inlines.silk_SMLAWB(19661, 65536 - Inlines.silk_SMULWB(262144 - Inlines.silk_LSHIFT(psEncCtrl.coding_quality_Q14, 4), psEncCtrl.input_quality_Q14), 13107); a6 = Inlines.silk_SMULWB(Inlines.silk_LSHIFT(a6, 1), Inlines.silk_SQRT_APPROX(Inlines.silk_LSHIFT(psEnc.LTPCorr_Q15, 15))); } else { a6 = 0; } for (int i = 0; i < 4; i++) { sShape.HarmBoost_smth_Q16 = Inlines.silk_SMLAWB(sShape.HarmBoost_smth_Q16, a5 - sShape.HarmBoost_smth_Q16, 26214); sShape.HarmShapeGain_smth_Q16 = Inlines.silk_SMLAWB(sShape.HarmShapeGain_smth_Q16, a6 - sShape.HarmShapeGain_smth_Q16, 26214); sShape.Tilt_smth_Q16 = Inlines.silk_SMLAWB(sShape.Tilt_smth_Q16, num17 - sShape.Tilt_smth_Q16, 26214); psEncCtrl.HarmBoost_Q14[i] = Inlines.silk_RSHIFT_ROUND(sShape.HarmBoost_smth_Q16, 2); psEncCtrl.HarmShapeGain_Q14[i] = Inlines.silk_RSHIFT_ROUND(sShape.HarmShapeGain_smth_Q16, 2); psEncCtrl.Tilt_Q14[i] = Inlines.silk_RSHIFT_ROUND(sShape.Tilt_smth_Q16, 2); } } } internal static class PitchAnalysisCore { private class silk_pe_stage3_vals { internal readonly int[] Values = new int[5]; } private const int SCRATCH_SIZE = 22; private const int SF_LENGTH_4KHZ = 20; private const int SF_LENGTH_8KHZ = 40; private const int MIN_LAG_4KHZ = 8; private const int MIN_LAG_8KHZ = 16; private const int MAX_LAG_4KHZ = 72; private const int MAX_LAG_8KHZ = 143; private const int CSTRIDE_4KHZ = 65; private const int CSTRIDE_8KHZ = 132; private const int D_COMP_MIN = 13; private const int D_COMP_MAX = 147; private const int D_COMP_STRIDE = 134; internal static int silk_pitch_analysis_core(short[] frame, int[] pitch_out, BoxedValueShort lagIndex, BoxedValueSbyte contourIndex, BoxedValueInt LTPCorr_Q15, int prevLag, int search_thres1_Q16, int search_thres2_Q13, int Fs_kHz, int complexity, int nb_subfr) { int[] array = new int[6]; int[] array2 = new int[24]; int[] array3 = new int[11]; int num = (20 + nb_subfr * 5) * Fs_kHz; int num2 = (20 + nb_subfr * 5) * 4; int num3 = (20 + nb_subfr * 5) * 8; int num4 = 5 * Fs_kHz; int num5 = 2 * Fs_kHz; int num6 = 18 * Fs_kHz - 1; short[] array4 = new short[num3]; switch (Fs_kHz) { case 16: Arrays.MemSetInt(array, 0, 2); Resampler.silk_resampler_down2(array, array4, frame, num); break; case 12: Arrays.MemSetInt(array, 0, 6); Resampler.silk_resampler_down2_3(array, array4, frame, num); break; default: Arrays.MemCopy(frame, 0, array4, 0, num3); break; } Arrays.MemSetInt(array, 0, 2); short[] array5 = new short[num2]; Resampler.silk_resampler_down2(array, array5, array4, num3); for (int num7 = num2 - 1; num7 > 0; num7--) { array5[num7] = Inlines.silk_ADD_SAT16(array5[num7], array5[num7 - 1]); } SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, array5, num2); if (shift > 0) { shift = Inlines.silk_RSHIFT(shift, 1); for (int num7 = 0; num7 < num2; num7++) { array5[num7] = Inlines.silk_RSHIFT16(array5[num7], shift); } } short[] array6 = new short[nb_subfr * 132]; int[] array7 = new int[65]; Arrays.MemSetShort(array6, 0, (nb_subfr >> 1) * 65); short[] array8 = array5; int num8 = Inlines.silk_LSHIFT(20, 2); for (int i = 0; i < nb_subfr >> 1; i++) { short[] array9 = array8; int num9 = num8 - 8; CeltPitchXCorr.pitch_xcorr(array8, num8, array8, num8 - 72, array7, 40, 65); int a = array7[64]; int a2 = Inlines.silk_inner_prod_self(array8, num8, 40); a2 = Inlines.silk_ADD32(a2, Inlines.silk_inner_prod_self(array9, num9, 40)); a2 = Inlines.silk_ADD32(a2, Inlines.silk_SMULBB(40, 4000)); Inlines.MatrixSet(array6, i, 0, 65, (short)Inlines.silk_DIV32_varQ(a, a2, 14)); for (int j = 9; j <= 72; j++) { num9--; a = array7[72 - j]; a2 = Inlines.silk_ADD32(a2, Inlines.silk_SMULBB(array9[num9], array9[num9]) - Inlines.silk_SMULBB(array9[num9 + 40], array9[num9 + 40])); Inlines.MatrixSet(array6, i, j - 8, 65, (short)Inlines.silk_DIV32_varQ(a, a2, 14)); } num8 += 40; } if (nb_subfr == 4) { for (int num7 = 72; num7 >= 8; num7--) { int num10 = Inlines.MatrixGet(array6, 0, num7 - 8, 65) + Inlines.MatrixGet(array6, 1, num7 - 8, 65); num10 = Inlines.silk_SMLAWB(num10, num10, Inlines.silk_LSHIFT(-num7, 4)); array6[num7 - 8] = (short)num10; } } else { for (int num7 = 72; num7 >= 8; num7--) { int num10 = Inlines.silk_LSHIFT(array6[num7 - 8], 1); num10 = Inlines.silk_SMLAWB(num10, num10, Inlines.silk_LSHIFT(-num7, 4)); array6[num7 - 8] = (short)num10; } } int num11 = Inlines.silk_ADD_LSHIFT32(4, complexity, 1); Sort.silk_insertion_sort_decreasing_int16(array6, array2, 65, num11); int num12 = array6[0]; if (num12 < 3277) { Arrays.MemSetInt(pitch_out, 0, nb_subfr); LTPCorr_Q15.Val = 0; lagIndex.Val = 0; contourIndex.Val = 0; return 1; } int num13 = Inlines.silk_SMULWB(search_thres1_Q16, num12); for (int num7 = 0; num7 < num11; num7++) { if (array6[num7] > num13) { array2[num7] = Inlines.silk_LSHIFT(array2[num7] + 8, 1); continue; } num11 = num7; break; } short[] array10 = new short[134]; for (int num7 = 13; num7 < 147; num7++) { array10[num7 - 13] = 0; } for (int num7 = 0; num7 < num11; num7++) { array10[array2[num7] - 13] = 1; } for (int num7 = 146; num7 >= 16; num7--) { array10[num7 - 13] += (short)(array10[num7 - 1 - 13] + array10[num7 - 2 - 13]); } num11 = 0; for (int num7 = 16; num7 < 144; num7++) { if (array10[num7 + 1 - 13] > 0) { array2[num11] = num7; num11++; } } for (int num7 = 146; num7 >= 16; num7--) { array10[num7 - 13] += (short)(array10[num7 - 1 - 13] + array10[num7 - 2 - 13] + array10[num7 - 3 - 13]); } int num14 = 0; for (int num7 = 16; num7 < 147; num7++) { if (array10[num7 - 13] > 0) { array10[num14] = (short)(num7 - 2); num14++; } } SumSqrShift.silk_sum_sqr_shift(out energy, out shift, array4, num3); if (shift > 0) { shift = Inlines.silk_RSHIFT(shift, 1); for (int num7 = 0; num7 < num3; num7++) { array4[num7] = Inlines.silk_RSHIFT16(array4[num7], shift); } } Arrays.MemSetShort(array6, 0, nb_subfr * 132); array8 = array4; num8 = 160; for (int i = 0; i < nb_subfr; i++) { int a3 = Inlines.silk_ADD32(Inlines.silk_inner_prod(array8, num8, array8, num8, 40), 1); for (int k = 0; k < num14; k++) { int j = array10[k]; short[] array9 = array8; int num9 = num8 - j; int a = Inlines.silk_inner_prod(array8, num8, array9, num9, 40); if (a > 0) { int b = Inlines.silk_inner_prod_self(array9, num9, 40); Inlines.MatrixSet(array6, i, j - 14, 132, (short)Inlines.silk_DIV32_varQ(a, Inlines.silk_ADD32(a3, b), 14)); } else { Inlines.MatrixSet(array6, i, j - 14, 132, (short)0); } } num8 += 40; } int a4 = int.MinValue; int num15 = int.MinValue; int num16 = 0; int num17 = -1; int num18; if (prevLag > 0) { switch (Fs_kHz) { case 12: prevLag = Inlines.silk_DIV32_16(Inlines.silk_LSHIFT(prevLag, 1), 3); break; case 16: prevLag = Inlines.silk_RSHIFT(prevLag, 1); break; } num18 = Inlines.silk_lin2log(prevLag); } else { num18 = 0; } int num19; sbyte[][] array11; if (nb_subfr == 4) { array11 = Tables.silk_CB_lags_stage2; num19 = ((Fs_kHz != 8 || complexity <= 0) ? 3 : 11); } else { array11 = Tables.silk_CB_lags_stage2_10_ms; num19 = 3; } for (int i = 0; i < num11; i++) { int j = array2[i]; for (int k = 0; k < num19; k++) { array3[k] = 0; for (int num7 = 0; num7 < nb_subfr; num7++) { int num20 = j + array11[num7][k]; array3[k] += Inlines.MatrixGet(array6, num7, num20 - 14, 132); } } int num21 = int.MinValue; int num22 = 0; for (int num7 = 0; num7 < num19; num7++) { if (array3[num7] > num21) { num21 = array3[num7]; num22 = num7; } } int num23 = Inlines.silk_lin2log(j); int num24 = num21 - Inlines.silk_RSHIFT(Inlines.silk_SMULBB(nb_subfr * 1638, num23), 7); if (prevLag > 0) { int num25 = num23 - num18; num25 = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(num25, num25), 7); int a5 = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(nb_subfr * 1638, LTPCorr_Q15.Val), 15); a5 = Inlines.silk_DIV32(Inlines.silk_MUL(a5, num25), num25 + 64); num24 -= a5; } if (num24 > num15 && num21 > Inlines.silk_SMULBB(nb_subfr, search_thres2_Q13) && Tables.silk_CB_lags_stage2[0][num22] <= 16) { num15 = num24; a4 = num21; num17 = j; num16 = num22; } } if (num17 == -1) { Arrays.MemSetInt(pitch_out, 0, nb_subfr); LTPCorr_Q15.Val = 0; lagIndex.Val = 0; contourIndex.Val = 0; return 1; } LTPCorr_Q15.Val = Inlines.silk_LSHIFT(Inlines.silk_DIV32_16(a4, nb_subfr), 2); if (Fs_kHz > 8) { SumSqrShift.silk_sum_sqr_shift(out energy, out shift, frame, num); short[] array13; if (shift > 0) { short[] array12 = new short[num]; shift = Inlines.silk_RSHIFT(shift, 1); for (int num7 = 0; num7 < num; num7++) { array12[num7] = Inlines.silk_RSHIFT16(frame[num7], shift); } array13 = array12; } else { array13 = frame; } int num26 = num16; num17 = Inlines.silk_LIMIT_int(Fs_kHz switch { 12 => Inlines.silk_RSHIFT(Inlines.silk_SMULBB(num17, 3), 1), 16 => Inlines.silk_LSHIFT(num17, 1), _ => Inlines.silk_SMULBB(num17, 3), }, num5, num6); int num27 = Inlines.silk_max_int(num17 - 2, num5); int num28 = Inlines.silk_min_int(num17 + 2, num6); int num29 = num17; num16 = 0; a4 = int.MinValue; for (int i = 0; i < nb_subfr; i++) { pitch_out[i] = num17 + 2 * Tables.silk_CB_lags_stage2[i][num26]; } if (nb_subfr == 4) { num19 = Tables.silk_nb_cbk_searchs_stage3[complexity]; array11 = Tables.silk_CB_lags_stage3; } else { num19 = 12; array11 = Tables.silk_CB_lags_stage3_10_ms; } silk_pe_stage3_vals[] array14 = new silk_pe_stage3_vals[nb_subfr * num19]; silk_pe_stage3_vals[] array15 = new silk_pe_stage3_vals[nb_subfr * num19]; for (int l = 0; l < nb_subfr * num19; l++) { array14[l] = new silk_pe_stage3_vals(); array15[l] = new silk_pe_stage3_vals(); } silk_P_Ana_calc_corr_st3(array15, array13, num27, num4, nb_subfr, complexity); silk_P_Ana_calc_energy_st3(array14, array13, num27, num4, nb_subfr, complexity); int num30 = 0; int a6 = Inlines.silk_DIV32_16(1638, num17); array8 = array13; num8 = 20 * Fs_kHz; int a3 = Inlines.silk_ADD32(Inlines.silk_inner_prod_self(array8, num8, nb_subfr * num4), 1); for (int j = num27; j <= num28; j++) { for (int k = 0; k < num19; k++) { int a = 0; energy = a3; for (int i = 0; i < nb_subfr; i++) { a = Inlines.silk_ADD32(a, Inlines.MatrixGet(array15, i, k, num19).Values[num30]); energy = Inlines.silk_ADD32(energy, Inlines.MatrixGet(array14, i, k, num19).Values[num30]); } int num21; if (a > 0) { num21 = Inlines.silk_DIV32_varQ(a, energy, 14); int b2 = 32767 - Inlines.silk_MUL(a6, k); num21 = Inlines.silk_SMULWB(num21, b2); } else { num21 = 0; } if (num21 > a4 && j + Tables.silk_CB_lags_stage3[0][k] <= num6) { a4 = num21; num29 = j; num16 = k; } } num30++; } for (int i = 0; i < nb_subfr; i++) { pitch_out[i] = num29 + array11[i][num16]; pitch_out[i] = Inlines.silk_LIMIT(pitch_out[i], num5, 18 * Fs_kHz); } lagIndex.Val = (short)(num29 - num5); contourIndex.Val = (sbyte)num16; } else { for (int i = 0; i < nb_subfr; i++) { pitch_out[i] = num17 + array11[i][num16]; pitch_out[i] = Inlines.silk_LIMIT(pitch_out[i], 16, 144); } lagIndex.Val = (short)(num17 - 16); contourIndex.Val = (sbyte)num16; } return 0; } private static void silk_P_Ana_calc_corr_st3(silk_pe_stage3_vals[] cross_corr_st3, short[] frame, int start_lag, int sf_length, int nb_subfr, int complexity) { sbyte[][] array; sbyte[][] array2; int num; if (nb_subfr == 4) { array = Tables.silk_Lag_range_stage3[complexity]; array2 = Tables.silk_CB_lags_stage3; num = Tables.silk_nb_cbk_searchs_stage3[complexity]; } else { array = Tables.silk_Lag_range_stage3_10_ms; array2 = Tables.silk_CB_lags_stage3_10_ms; num = 12; } int[] array3 = new int[22]; int[] array4 = new int[22]; int num2 = Inlines.silk_LSHIFT(sf_length, 2); for (int i = 0; i < nb_subfr; i++) { int num3 = 0; int num4 = array[i][0]; int num5 = array[i][1]; CeltPitchXCorr.pitch_xcorr(frame, num2, frame, num2 - start_lag - num5, array4, sf_length, num5 - num4 + 1); for (int j = num4; j <= num5; j++) { array3[num3] = array4[num5 - j]; num3++; } int num6 = array[i][0]; for (int k = 0; k < num; k++) { int num7 = array2[i][k] - num6; for (int j = 0; j < 5; j++) { Inlines.MatrixGet(cross_corr_st3, i, k, num).Values[j] = array3[num7 + j]; } } num2 += sf_length; } } private static void silk_P_Ana_calc_energy_st3(silk_pe_stage3_vals[] energies_st3, short[] frame, int start_lag, int sf_length, int nb_subfr, int complexity) { sbyte[][] array; sbyte[][] array2; int num; if (nb_subfr == 4) { array = Tables.silk_Lag_range_stage3[complexity]; array2 = Tables.silk_CB_lags_stage3; num = Tables.silk_nb_cbk_searchs_stage3[complexity]; } else { array = Tables.silk_Lag_range_stage3_10_ms; array2 = Tables.silk_CB_lags_stage3_10_ms; num = 12; } int[] array3 = new int[22]; int num2 = Inlines.silk_LSHIFT(sf_length, 2); for (int i = 0; i < nb_subfr; i++) { int num3 = 0; int num4 = num2 - (start_lag + array[i][0]); int num5 = (array3[num3] = Inlines.silk_inner_prod_self(frame, num4, sf_length)); num3++; int num6 = array[i][1] - array[i][0] + 1; for (int j = 1; j < num6; j++) { num5 -= Inlines.silk_SMULBB(frame[num4 + sf_length - j], frame[num4 + sf_length - j]); num5 = (array3[num3] = Inlines.silk_ADD_SAT32(num5, Inlines.silk_SMULBB(frame[num4 - j], frame[num4 - j]))); num3++; } int num7 = array[i][0]; for (int j = 0; j < num; j++) { int num8 = array2[i][j] - num7; for (int k = 0; k < 5; k++) { Inlines.MatrixGet(energies_st3, i, j, num).Values[k] = array3[num8 + k]; } } num2 += sf_length; } } } internal static class PLC { private const int NB_ATT = 2; private static readonly short[] HARM_ATT_Q15 = new short[2] { 32440, 31130 }; private static readonly short[] PLC_RAND_ATTENUATE_V_Q15 = new short[2] { 31130, 26214 }; private static readonly short[] PLC_RAND_ATTENUATE_UV_Q15 = new short[2] { 32440, 29491 }; internal static void silk_PLC_Reset(SilkChannelDecoder psDec) { psDec.sPLC.pitchL_Q8 = Inlines.silk_LSHIFT(psDec.frame_length, 7); psDec.sPLC.prevGain_Q16[0] = 65536; psDec.sPLC.prevGain_Q16[1] = 65536; psDec.sPLC.subfr_length = 20; psDec.sPLC.nb_subfr = 2; } internal static void silk_PLC(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span frame, int frame_ptr, int lost) { if (psDec.fs_kHz != psDec.sPLC.fs_kHz) { silk_PLC_Reset(psDec); psDec.sPLC.fs_kHz = psDec.fs_kHz; } if (lost != 0) { silk_PLC_conceal(psDec, psDecCtrl, frame, frame_ptr); psDec.lossCnt++; } else { silk_PLC_update(psDec, psDecCtrl); } } internal static void silk_PLC_update(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl) { PLCStruct sPLC = psDec.sPLC; psDec.prevSignalType = psDec.indices.signalType; int num = 0; if (psDec.indices.signalType == 2) { for (int i = 0; i * psDec.subfr_length < psDecCtrl.pitchL[psDec.nb_subfr - 1] && i != psDec.nb_subfr; i++) { int num2 = 0; for (int j = 0; j < 5; j++) { num2 += psDecCtrl.LTPCoef_Q14[(psDec.nb_subfr - 1 - i) * 5 + j]; } if (num2 > num) { num = num2; Arrays.MemCopy(psDecCtrl.LTPCoef_Q14, Inlines.silk_SMULBB(psDec.nb_subfr - 1 - i, 5), sPLC.LTPCoef_Q14, 0, 5); sPLC.pitchL_Q8 = Inlines.silk_LSHIFT(psDecCtrl.pitchL[psDec.nb_subfr - 1 - i], 8); } } Arrays.MemSetShort(sPLC.LTPCoef_Q14, 0, 5); sPLC.LTPCoef_Q14[2] = (short)num; if (num < 11469) { int b = Inlines.silk_DIV32(Inlines.silk_LSHIFT(11469, 10), Inlines.silk_max(num, 1)); for (int j = 0; j < 5; j++) { sPLC.LTPCoef_Q14[j] = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(sPLC.LTPCoef_Q14[j], b), 10); } } else if (num > 15565) { int b2 = Inlines.silk_DIV32(Inlines.silk_LSHIFT(15565, 14), Inlines.silk_max(num, 1)); for (int j = 0; j < 5; j++) { sPLC.LTPCoef_Q14[j] = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(sPLC.LTPCoef_Q14[j], b2), 14); } } } else { sPLC.pitchL_Q8 = Inlines.silk_LSHIFT(Inlines.silk_SMULBB(psDec.fs_kHz, 18), 8); Arrays.MemSetShort(sPLC.LTPCoef_Q14, 0, 5); } Arrays.MemCopy(psDecCtrl.PredCoef_Q12[1], 0, sPLC.prevLPC_Q12, 0, psDec.LPC_order); sPLC.prevLTP_scale_Q14 = (short)psDecCtrl.LTP_scale_Q14; Arrays.MemCopy(psDecCtrl.Gains_Q16, psDec.nb_subfr - 2, sPLC.prevGain_Q16, 0, 2); sPLC.subfr_length = psDec.subfr_length; sPLC.nb_subfr = psDec.nb_subfr; } internal static void silk_PLC_energy(out int energy1, out int shift1, out int energy2, out int shift2, int[] exc_Q14, int[] prevGain_Q10, int subfr_length, int nb_subfr) { int num = 0; short[] array = new short[2 * subfr_length]; for (int i = 0; i < 2; i++) { for (int j = 0; j < subfr_length; j++) { array[num + j] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT(Inlines.silk_SMULWW(exc_Q14[j + (i + nb_subfr - 2) * subfr_length], prevGain_Q10[i]), 8)); } num += subfr_length; } SumSqrShift.silk_sum_sqr_shift(out energy1, out shift1, array, subfr_length); SumSqrShift.silk_sum_sqr_shift(out energy2, out shift2, array, subfr_length, subfr_length); } internal static void silk_PLC_conceal(SilkChannelDecoder psDec, SilkDecoderControl psDecCtrl, Span frame, int frame_ptr) { short[] array = new short[psDec.ltp_mem_length]; int[] array2 = new int[psDec.ltp_mem_length + psDec.frame_length]; PLCStruct sPLC = psDec.sPLC; int[] array3 = new int[2] { Inlines.silk_RSHIFT(sPLC.prevGain_Q16[0], 6), Inlines.silk_RSHIFT(sPLC.prevGain_Q16[1], 6) }; if (psDec.first_frame_after_reset != 0) { Arrays.MemSetShort(sPLC.prevLPC_Q12, 0, 16); } silk_PLC_energy(out var energy, out var shift, out var energy2, out var shift2, psDec.exc_Q14, array3, psDec.subfr_length, psDec.nb_subfr); int num = ((Inlines.silk_RSHIFT(energy, shift2) >= Inlines.silk_RSHIFT(energy2, shift)) ? Inlines.silk_max_int(0, sPLC.nb_subfr * sPLC.subfr_length - 128) : Inlines.silk_max_int(0, (sPLC.nb_subfr - 1) * sPLC.subfr_length - 128)); short[] lTPCoef_Q = sPLC.LTPCoef_Q14; short num2 = sPLC.randScale_Q14; int a = HARM_ATT_Q15[Inlines.silk_min_int(1, psDec.lossCnt)]; int b = ((psDec.prevSignalType != 2) ? PLC_RAND_ATTENUATE_UV_Q15[Inlines.silk_min_int(1, psDec.lossCnt)] : PLC_RAND_ATTENUATE_V_Q15[Inlines.silk_min_int(1, psDec.lossCnt)]); BWExpander.silk_bwexpander(sPLC.prevLPC_Q12, psDec.LPC_order, 64881); if (psDec.lossCnt == 0) { num2 = 16384; if (psDec.prevSignalType == 2) { for (int i = 0; i < 5; i++) { num2 -= lTPCoef_Q[i]; } num2 = Inlines.silk_max_16(3277, num2); num2 = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(num2, sPLC.prevLTP_scale_Q14), 14); } else { int b2 = LPCInversePredGain.silk_LPC_inverse_pred_gain(sPLC.prevLPC_Q12, psDec.LPC_order); int b3 = Inlines.silk_min_32(Inlines.silk_RSHIFT(1073741824, 3), b2); b3 = Inlines.silk_max_32(Inlines.silk_RSHIFT(1073741824, 8), b3); b3 = Inlines.silk_LSHIFT(b3, 3); b = Inlines.silk_RSHIFT(Inlines.silk_SMULWB(b3, b), 14); } } int num3 = sPLC.rand_seed; int num4 = Inlines.silk_RSHIFT_ROUND(sPLC.pitchL_Q8, 8); int num5 = psDec.ltp_mem_length; int num6 = psDec.ltp_mem_length - num4 - psDec.LPC_order - 2; Filters.silk_LPC_analysis_filter(array, num6, psDec.outBuf, num6, sPLC.prevLPC_Q12, 0, psDec.ltp_mem_length - num6, psDec.LPC_order); int a2 = Inlines.silk_INVERSE32_varQ(sPLC.prevGain_Q16[1], 46); a2 = Inlines.silk_min(a2, 1073741823); for (int i = num6 + psDec.LPC_order; i < psDec.ltp_mem_length; i++) { array2[i] = Inlines.silk_SMULWB(a2, array[i]); } for (int j = 0; j < psDec.nb_subfr; j++) { int num7 = num5 - num4 + 2; for (int i = 0; i < psDec.subfr_length; i++) { int a3 = 2; a3 = Inlines.silk_SMLAWB(a3, array2[num7], lTPCoef_Q[0]); a3 = Inlines.silk_SMLAWB(a3, array2[num7 - 1], lTPCoef_Q[1]); a3 = Inlines.silk_SMLAWB(a3, array2[num7 - 2], lTPCoef_Q[2]); a3 = Inlines.silk_SMLAWB(a3, array2[num7 - 3], lTPCoef_Q[3]); a3 = Inlines.silk_SMLAWB(a3, array2[num7 - 4], lTPCoef_Q[4]); num7++; num3 = Inlines.silk_RAND(num3); num6 = Inlines.silk_RSHIFT(num3, 25) & 0x7F; array2[num5] = Inlines.silk_LSHIFT32(Inlines.silk_SMLAWB(a3, psDec.exc_Q14[num + num6], num2), 2); num5++; } for (int k = 0; k < 5; k++) { lTPCoef_Q[k] = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(a, lTPCoef_Q[k]), 15); } num2 = (short)Inlines.silk_RSHIFT(Inlines.silk_SMULBB(num2, b), 15); sPLC.pitchL_Q8 = Inlines.silk_SMLAWB(sPLC.pitchL_Q8, sPLC.pitchL_Q8, 655); sPLC.pitchL_Q8 = Inlines.silk_min_32(sPLC.pitchL_Q8, Inlines.silk_LSHIFT(Inlines.silk_SMULBB(18, psDec.fs_kHz), 8)); num4 = Inlines.silk_RSHIFT_ROUND(sPLC.pitchL_Q8, 8); } int num8 = psDec.ltp_mem_length - 16; Arrays.MemCopy(psDec.sLPC_Q14_buf, 0, array2, num8, 16); for (int i = 0; i < psDec.frame_length; i++) { int num9 = num8 + 16 + i; int a4 = Inlines.silk_RSHIFT(psDec.LPC_order, 1); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 1], sPLC.prevLPC_Q12[0]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 2], sPLC.prevLPC_Q12[1]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 3], sPLC.prevLPC_Q12[2]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 4], sPLC.prevLPC_Q12[3]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 5], sPLC.prevLPC_Q12[4]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 6], sPLC.prevLPC_Q12[5]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 7], sPLC.prevLPC_Q12[6]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 8], sPLC.prevLPC_Q12[7]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 9], sPLC.prevLPC_Q12[8]); a4 = Inlines.silk_SMLAWB(a4, array2[num9 - 10], sPLC.prevLPC_Q12[9]); for (int k = 10; k < psDec.LPC_order; k++) { a4 = Inlines.silk_SMLAWB(a4, array2[num9 - k - 1], sPLC.prevLPC_Q12[k]); } array2[num9] = Inlines.silk_ADD_LSHIFT32(array2[num9], a4, 4); frame[frame_ptr + i] = (short)Inlines.silk_SAT16(Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(array2[num9], array3[1]), 8))); } Arrays.MemCopy(array2, num8 + psDec.frame_length, psDec.sLPC_Q14_buf, 0, 16); sPLC.rand_seed = num3; sPLC.randScale_Q14 = num2; for (int i = 0; i < 4; i++) { psDecCtrl.pitchL[i] = num4; } } internal static void silk_PLC_glue_frames(SilkChannelDecoder psDec, Span frame, int frame_ptr, int length) { PLCStruct sPLC = psDec.sPLC; if (psDec.lossCnt != 0) { SumSqrShift.silk_sum_sqr_shift(out sPLC.conc_energy, out sPLC.conc_energy_shift, frame, frame_ptr, length); sPLC.last_frame_lost = 1; return; } if (psDec.sPLC.last_frame_lost != 0) { SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, frame, frame_ptr, length); if (shift > sPLC.conc_energy_shift) { sPLC.conc_energy = Inlines.silk_RSHIFT(sPLC.conc_energy, shift - sPLC.conc_energy_shift); } else if (shift < sPLC.conc_energy_shift) { energy = Inlines.silk_RSHIFT(energy, sPLC.conc_energy_shift - shift); } if (energy > sPLC.conc_energy) { int num = Inlines.silk_CLZ32(sPLC.conc_energy); num--; sPLC.conc_energy = Inlines.silk_LSHIFT(sPLC.conc_energy, num); energy = Inlines.silk_RSHIFT(energy, Inlines.silk_max_32(24 - num, 0)); int num2 = Inlines.silk_LSHIFT(Inlines.silk_SQRT_APPROX(Inlines.silk_DIV32(sPLC.conc_energy, Inlines.silk_max(energy, 1))), 4); int a = Inlines.silk_DIV32_16(65536 - num2, length); a = Inlines.silk_LSHIFT(a, 2); for (int i = frame_ptr; i < frame_ptr + length; i++) { frame[i] = (short)Inlines.silk_SMULWB(num2, frame[i]); num2 += a; if (num2 > 65536) { break; } } } } sPLC.last_frame_lost = 0; } } internal static class ProcessGains { internal static void silk_process_gains(SilkChannelEncoder psEnc, SilkEncoderControl psEncCtrl, int condCoding) { SilkShapeState sShape = psEnc.sShape; if (psEnc.indices.signalType == 2) { int c = -Sigmoid.silk_sigm_Q15(Inlines.silk_RSHIFT_ROUND(psEncCtrl.LTPredCodGain_Q7 - 1536, 4)); for (int i = 0; i < psEnc.nb_subfr; i++) { psEncCtrl.Gains_Q16[i] = Inlines.silk_SMLAWB(psEncCtrl.Gains_Q16[i], psEncCtrl.Gains_Q16[i], c); } } int b = Inlines.silk_DIV32_16(Inlines.silk_log2lin(Inlines.silk_SMULWB(8894 - psEnc.SNR_dB_Q7, 21627)), psEnc.subfr_length); for (int i = 0; i < psEnc.nb_subfr; i++) { int num = Inlines.silk_SMULWW(psEncCtrl.ResNrg[i], b); num = ((psEncCtrl.ResNrgQ[i] > 0) ? Inlines.silk_RSHIFT_ROUND(num, psEncCtrl.ResNrgQ[i]) : ((num < Inlines.silk_RSHIFT(int.MaxValue, -psEncCtrl.ResNrgQ[i])) ? Inlines.silk_LSHIFT(num, -psEncCtrl.ResNrgQ[i]) : int.MaxValue)); int num2 = psEncCtrl.Gains_Q16[i]; int num3 = Inlines.silk_ADD_SAT32(num, Inlines.silk_SMMUL(num2, num2)); if (num3 < 32767) { num3 = Inlines.silk_SMLAWW(Inlines.silk_LSHIFT(num, 16), num2, num2); num2 = Inlines.silk_SQRT_APPROX(num3); num2 = Inlines.silk_min(num2, 8388607); psEncCtrl.Gains_Q16[i] = Inlines.silk_LSHIFT_SAT32(num2, 8); } else { num2 = Inlines.silk_SQRT_APPROX(num3); num2 = Inlines.silk_min(num2, 32767); psEncCtrl.Gains_Q16[i] = Inlines.silk_LSHIFT_SAT32(num2, 16); } } Arrays.MemCopy(psEncCtrl.Gains_Q16, 0, psEncCtrl.GainsUnq_Q16, 0, psEnc.nb_subfr); psEncCtrl.lastGainIndexPrev = sShape.LastGainIndex; BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(sShape.LastGainIndex); GainQuantization.silk_gains_quant(psEnc.indices.GainsIndices, psEncCtrl.Gains_Q16, boxedValueSbyte, (condCoding == 2) ? 1 : 0, psEnc.nb_subfr); sShape.LastGainIndex = boxedValueSbyte.Val; if (psEnc.indices.signalType == 2) { if (psEncCtrl.LTPredCodGain_Q7 + Inlines.silk_RSHIFT(psEnc.input_tilt_Q15, 8) > 128) { psEnc.indices.quantOffsetType = 0; } else { psEnc.indices.quantOffsetType = 1; } } int b2 = Tables.silk_Quantization_Offsets_Q10[psEnc.indices.signalType >> 1][psEnc.indices.quantOffsetType]; psEncCtrl.Lambda_Q10 = 1229 + Inlines.silk_SMULBB(-50, psEnc.nStatesDelayedDecision) + Inlines.silk_SMULWB(-52428, psEnc.speech_activity_Q8) + Inlines.silk_SMULWB(-409, psEncCtrl.input_quality_Q14) + Inlines.silk_SMULWB(-818, psEncCtrl.coding_quality_Q14) + Inlines.silk_SMULWB(52429, b2); } } internal static class QuantizeLTPGains { internal static void silk_quant_LTP_gains(short[] B_Q14, sbyte[] cbk_index, BoxedValueSbyte periodicity_index, BoxedValueInt sum_log_gain_Q7, int[] W_Q18, int mu_Q9, int lowComplexity, int nb_subfr) { sbyte[] array = new sbyte[4]; int num = int.MaxValue; int val = 0; sbyte[][] cb_Q; for (int i = 0; i < 3; i++) { int num2 = 51; byte[] cl_Q = Tables.silk_LTP_gain_BITS_Q5_ptrs[i]; cb_Q = Tables.silk_LTP_vq_ptrs_Q7[i]; byte[] cb_gain_Q = Tables.silk_LTP_vq_gain_ptrs_Q7[i]; int l = Tables.silk_LTP_vq_sizes[i]; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = sum_log_gain_Q7.Val; for (int j = 0; j < nb_subfr; j++) { int max_gain_Q = Inlines.silk_log2lin(5333 - num6 + 896) - num2; BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(array[j]); BoxedValueInt boxedValueInt = new BoxedValueInt(); BoxedValueInt boxedValueInt2 = new BoxedValueInt(); VQ_WMat_EC.silk_VQ_WMat_EC(boxedValueSbyte, boxedValueInt, boxedValueInt2, B_Q14, num4, W_Q18, num3, cb_Q, cb_gain_Q, cl_Q, mu_Q9, max_gain_Q, l); int val2 = boxedValueInt.Val; int val3 = boxedValueInt2.Val; array[j] = boxedValueSbyte.Val; num5 = Inlines.silk_ADD_POS_SAT32(num5, val2); num6 = Inlines.silk_max(0, num6 + Inlines.silk_lin2log(num2 + val3) - 896); num4 += 5; num3 += 25; } num5 = Inlines.silk_min(2147483646, num5); if (num5 < num) { num = num5; periodicity_index.Val = (sbyte)i; Arrays.MemCopy(array, 0, cbk_index, 0, nb_subfr); val = num6; } if (lowComplexity != 0 && num5 < Tables.silk_LTP_gain_middle_avg_RD_Q14) { break; } } cb_Q = Tables.silk_LTP_vq_ptrs_Q7[periodicity_index.Val]; for (int j = 0; j < nb_subfr; j++) { for (int i = 0; i < 5; i++) { B_Q14[j * 5 + i] = (short)Inlines.silk_LSHIFT(cb_Q[cbk_index[j]][i], 7); } } sum_log_gain_Q7.Val = val; } } internal static class RegularizeCorrelations { internal static void silk_regularize_correlations(int[] XX, int XX_ptr, int[] xx, int xx_ptr, int noise, int D) { for (int i = 0; i < D; i++) { Inlines.MatrixSet(XX, XX_ptr, i, i, D, Inlines.silk_ADD32(Inlines.MatrixGet(XX, XX_ptr, i, i, D), noise)); } xx[xx_ptr] += noise; } } internal static class Resampler { private const int USE_silk_resampler_copy = 0; private const int USE_silk_resampler_private_up2_HQ_wrapper = 1; private const int USE_silk_resampler_private_IIR_FIR = 2; private const int USE_silk_resampler_private_down_FIR = 3; private const int ORDER_FIR = 4; private static int rateID(int R) { return ((R >> 12) - ((R > 16000) ? 1 : 0) >> ((R > 24000) ? 1 : 0)) - 1; } internal static int silk_resampler_init(SilkResamplerState S, int Fs_Hz_in, int Fs_Hz_out, int forEnc) { S.Reset(); if (forEnc != 0) { if ((Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000) || (Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000)) { return -1; } S.inputDelay = Tables.delay_matrix_enc[rateID(Fs_Hz_in), rateID(Fs_Hz_out)]; } else { if ((Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000) || (Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000)) { return -1; } S.inputDelay = Tables.delay_matrix_dec[rateID(Fs_Hz_in), rateID(Fs_Hz_out)]; } S.Fs_in_kHz = Inlines.silk_DIV32_16(Fs_Hz_in, 1000); S.Fs_out_kHz = Inlines.silk_DIV32_16(Fs_Hz_out, 1000); S.batchSize = S.Fs_in_kHz * 10; int num = 0; if (Fs_Hz_out > Fs_Hz_in) { if (Fs_Hz_out == Inlines.silk_MUL(Fs_Hz_in, 2)) { S.resampler_function = 1; } else { S.resampler_function = 2; num = 1; } } else if (Fs_Hz_out < Fs_Hz_in) { S.resampler_function = 3; if (Inlines.silk_MUL(Fs_Hz_out, 4) == Inlines.silk_MUL(Fs_Hz_in, 3)) { S.FIR_Fracs = 3; S.FIR_Order = 18; S.Coefs = Tables.silk_Resampler_3_4_COEFS; } else if (Inlines.silk_MUL(Fs_Hz_out, 3) == Inlines.silk_MUL(Fs_Hz_in, 2)) { S.FIR_Fracs = 2; S.FIR_Order = 18; S.Coefs = Tables.silk_Resampler_2_3_COEFS; } else if (Inlines.silk_MUL(Fs_Hz_out, 2) == Fs_Hz_in) { S.FIR_Fracs = 1; S.FIR_Order = 24; S.Coefs = Tables.silk_Resampler_1_2_COEFS; } else if (Inlines.silk_MUL(Fs_Hz_out, 3) == Fs_Hz_in) { S.FIR_Fracs = 1; S.FIR_Order = 36; S.Coefs = Tables.silk_Resampler_1_3_COEFS; } else if (Inlines.silk_MUL(Fs_Hz_out, 4) == Fs_Hz_in) { S.FIR_Fracs = 1; S.FIR_Order = 36; S.Coefs = Tables.silk_Resampler_1_4_COEFS; } else { if (Inlines.silk_MUL(Fs_Hz_out, 6) != Fs_Hz_in) { return -1; } S.FIR_Fracs = 1; S.FIR_Order = 36; S.Coefs = Tables.silk_Resampler_1_6_COEFS; } } else { S.resampler_function = 0; } S.invRatio_Q16 = Inlines.silk_LSHIFT32(Inlines.silk_DIV32(Inlines.silk_LSHIFT32(Fs_Hz_in, 14 + num), Fs_Hz_out), 2); while (Inlines.silk_SMULWW(S.invRatio_Q16, Fs_Hz_out) < Inlines.silk_LSHIFT32(Fs_Hz_in, num)) { S.invRatio_Q16++; } return 0; } internal static int silk_resampler(SilkResamplerState S, Span output, int output_ptr, Span input, int input_ptr, int inLen) { int num = S.Fs_in_kHz - S.inputDelay; short[] delayBuf = S.delayBuf; input.Slice(input_ptr, num).CopyTo(MemoryExtensions.AsSpan(delayBuf, S.inputDelay)); switch (S.resampler_function) { case 1: silk_resampler_private_up2_HQ(S.sIIR, output, output_ptr, delayBuf, 0, S.Fs_in_kHz); silk_resampler_private_up2_HQ(S.sIIR, output, output_ptr + S.Fs_out_kHz, input, input_ptr + num, inLen - S.Fs_in_kHz); break; case 2: silk_resampler_private_IIR_FIR(S, output, output_ptr, delayBuf, 0, S.Fs_in_kHz); silk_resampler_private_IIR_FIR(S, output, output_ptr + S.Fs_out_kHz, input, input_ptr + num, inLen - S.Fs_in_kHz); break; case 3: silk_resampler_private_down_FIR(S, output, output_ptr, delayBuf, 0, S.Fs_in_kHz); silk_resampler_private_down_FIR(S, output, output_ptr + S.Fs_out_kHz, input, input_ptr + num, inLen - S.Fs_in_kHz); break; default: MemoryExtensions.AsSpan(delayBuf, 0, S.Fs_in_kHz).CopyTo(output.Slice(output_ptr)); input.Slice(input_ptr + num, inLen - S.Fs_in_kHz).CopyTo(output.Slice(output_ptr + S.Fs_out_kHz)); break; } input.Slice(input_ptr + inLen - S.inputDelay, S.inputDelay).CopyTo(delayBuf); return SilkError.SILK_NO_ERROR; } internal static void silk_resampler_down2(int[] S, short[] output, short[] input, int inLen) { int num = Inlines.silk_RSHIFT32(inLen, 1); for (int i = 0; i < num; i++) { int a = Inlines.silk_LSHIFT(input[2 * i], 10); int num2 = Inlines.silk_SUB32(a, S[0]); int b = Inlines.silk_SMLAWB(num2, num2, -25727); int a2 = Inlines.silk_ADD32(S[0], b); S[0] = Inlines.silk_ADD32(a, b); a = Inlines.silk_LSHIFT(input[2 * i + 1], 10); b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a, S[1]), 9872); a2 = Inlines.silk_ADD32(a2, S[1]); a2 = Inlines.silk_ADD32(a2, b); S[1] = Inlines.silk_ADD32(a, b); output[i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a2, 11)); } } internal static void silk_resampler_down2_3(int[] S, short[] output, short[] input, int inLen) { int[] array = new int[484]; int num = 0; int num2 = 0; Arrays.MemCopy(S, 0, array, 0, 4); int num3; while (true) { num3 = Inlines.silk_min(inLen, 480); silk_resampler_private_AR2(S, 4, array, 4, input, num, Tables.silk_Resampler_2_3_COEFS_LQ, num3); int num4 = 0; for (int num5 = num3; num5 > 2; num5 -= 3) { int a = Inlines.silk_SMULWB(array[num4], Tables.silk_Resampler_2_3_COEFS_LQ[2]); a = Inlines.silk_SMLAWB(a, array[num4 + 1], Tables.silk_Resampler_2_3_COEFS_LQ[3]); a = Inlines.silk_SMLAWB(a, array[num4 + 2], Tables.silk_Resampler_2_3_COEFS_LQ[5]); a = Inlines.silk_SMLAWB(a, array[num4 + 3], Tables.silk_Resampler_2_3_COEFS_LQ[4]); output[num2++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 6)); a = Inlines.silk_SMULWB(array[num4 + 1], Tables.silk_Resampler_2_3_COEFS_LQ[4]); a = Inlines.silk_SMLAWB(a, array[num4 + 2], Tables.silk_Resampler_2_3_COEFS_LQ[5]); a = Inlines.silk_SMLAWB(a, array[num4 + 3], Tables.silk_Resampler_2_3_COEFS_LQ[3]); a = Inlines.silk_SMLAWB(a, array[num4 + 4], Tables.silk_Resampler_2_3_COEFS_LQ[2]); output[num2++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 6)); num4 += 3; } num += num3; inLen -= num3; if (inLen <= 0) { break; } Arrays.MemCopy(array, num3, array, 0, 4); } Arrays.MemCopy(array, num3, S, 0, 4); } internal static void silk_resampler_private_AR2(Span S, int S_ptr, Span out_Q8, int out_Q8_ptr, Span input, int input_ptr, short[] A_Q14, int len) { for (int i = 0; i < len; i++) { int num = Inlines.silk_ADD_LSHIFT32(S[S_ptr], input[input_ptr + i], 8); out_Q8[out_Q8_ptr + i] = num; num = Inlines.silk_LSHIFT(num, 2); S[S_ptr] = Inlines.silk_SMLAWB(S[S_ptr + 1], num, A_Q14[0]); S[S_ptr + 1] = Inlines.silk_SMULWB(num, A_Q14[1]); } } internal static int silk_resampler_private_down_FIR_INTERPOL(Span output, int output_ptr, int[] buf, Span FIR_Coefs, int FIR_Coefs_ptr, int FIR_Order, int FIR_Fracs, int max_index_Q16, int index_increment_Q16) { switch (FIR_Order) { case 18: { for (int i = 0; i < max_index_Q16; i += index_increment_Q16) { int num = Inlines.silk_RSHIFT(i, 16); int num2 = Inlines.silk_SMULWB(i & 0xFFFF, FIR_Fracs); int num3 = FIR_Coefs_ptr + 9 * num2; int a = Inlines.silk_SMULWB(buf[num], FIR_Coefs[num3]); a = Inlines.silk_SMLAWB(a, buf[num + 1], FIR_Coefs[num3 + 1]); a = Inlines.silk_SMLAWB(a, buf[num + 2], FIR_Coefs[num3 + 2]); a = Inlines.silk_SMLAWB(a, buf[num + 3], FIR_Coefs[num3 + 3]); a = Inlines.silk_SMLAWB(a, buf[num + 4], FIR_Coefs[num3 + 4]); a = Inlines.silk_SMLAWB(a, buf[num + 5], FIR_Coefs[num3 + 5]); a = Inlines.silk_SMLAWB(a, buf[num + 6], FIR_Coefs[num3 + 6]); a = Inlines.silk_SMLAWB(a, buf[num + 7], FIR_Coefs[num3 + 7]); a = Inlines.silk_SMLAWB(a, buf[num + 8], FIR_Coefs[num3 + 8]); num3 = FIR_Coefs_ptr + 9 * (FIR_Fracs - 1 - num2); a = Inlines.silk_SMLAWB(a, buf[num + 17], FIR_Coefs[num3]); a = Inlines.silk_SMLAWB(a, buf[num + 16], FIR_Coefs[num3 + 1]); a = Inlines.silk_SMLAWB(a, buf[num + 15], FIR_Coefs[num3 + 2]); a = Inlines.silk_SMLAWB(a, buf[num + 14], FIR_Coefs[num3 + 3]); a = Inlines.silk_SMLAWB(a, buf[num + 13], FIR_Coefs[num3 + 4]); a = Inlines.silk_SMLAWB(a, buf[num + 12], FIR_Coefs[num3 + 5]); a = Inlines.silk_SMLAWB(a, buf[num + 11], FIR_Coefs[num3 + 6]); a = Inlines.silk_SMLAWB(a, buf[num + 10], FIR_Coefs[num3 + 7]); a = Inlines.silk_SMLAWB(a, buf[num + 9], FIR_Coefs[num3 + 8]); output[output_ptr++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 6)); } break; } case 24: { for (int i = 0; i < max_index_Q16; i += index_increment_Q16) { int num = Inlines.silk_RSHIFT(i, 16); int a = Inlines.silk_SMULWB(Inlines.silk_ADD32(buf[num], buf[num + 23]), FIR_Coefs[FIR_Coefs_ptr]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 1], buf[num + 22]), FIR_Coefs[FIR_Coefs_ptr + 1]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 2], buf[num + 21]), FIR_Coefs[FIR_Coefs_ptr + 2]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 3], buf[num + 20]), FIR_Coefs[FIR_Coefs_ptr + 3]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 4], buf[num + 19]), FIR_Coefs[FIR_Coefs_ptr + 4]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 5], buf[num + 18]), FIR_Coefs[FIR_Coefs_ptr + 5]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 6], buf[num + 17]), FIR_Coefs[FIR_Coefs_ptr + 6]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 7], buf[num + 16]), FIR_Coefs[FIR_Coefs_ptr + 7]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 8], buf[num + 15]), FIR_Coefs[FIR_Coefs_ptr + 8]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 9], buf[num + 14]), FIR_Coefs[FIR_Coefs_ptr + 9]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 10], buf[num + 13]), FIR_Coefs[FIR_Coefs_ptr + 10]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 11], buf[num + 12]), FIR_Coefs[FIR_Coefs_ptr + 11]); output[output_ptr++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 6)); } break; } case 36: { for (int i = 0; i < max_index_Q16; i += index_increment_Q16) { int num = Inlines.silk_RSHIFT(i, 16); int a = Inlines.silk_SMULWB(Inlines.silk_ADD32(buf[num], buf[num + 35]), FIR_Coefs[FIR_Coefs_ptr]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 1], buf[num + 34]), FIR_Coefs[FIR_Coefs_ptr + 1]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 2], buf[num + 33]), FIR_Coefs[FIR_Coefs_ptr + 2]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 3], buf[num + 32]), FIR_Coefs[FIR_Coefs_ptr + 3]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 4], buf[num + 31]), FIR_Coefs[FIR_Coefs_ptr + 4]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 5], buf[num + 30]), FIR_Coefs[FIR_Coefs_ptr + 5]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 6], buf[num + 29]), FIR_Coefs[FIR_Coefs_ptr + 6]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 7], buf[num + 28]), FIR_Coefs[FIR_Coefs_ptr + 7]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 8], buf[num + 27]), FIR_Coefs[FIR_Coefs_ptr + 8]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 9], buf[num + 26]), FIR_Coefs[FIR_Coefs_ptr + 9]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 10], buf[num + 25]), FIR_Coefs[FIR_Coefs_ptr + 10]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 11], buf[num + 24]), FIR_Coefs[FIR_Coefs_ptr + 11]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 12], buf[num + 23]), FIR_Coefs[FIR_Coefs_ptr + 12]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 13], buf[num + 22]), FIR_Coefs[FIR_Coefs_ptr + 13]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 14], buf[num + 21]), FIR_Coefs[FIR_Coefs_ptr + 14]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 15], buf[num + 20]), FIR_Coefs[FIR_Coefs_ptr + 15]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 16], buf[num + 19]), FIR_Coefs[FIR_Coefs_ptr + 16]); a = Inlines.silk_SMLAWB(a, Inlines.silk_ADD32(buf[num + 17], buf[num + 18]), FIR_Coefs[FIR_Coefs_ptr + 17]); output[output_ptr++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 6)); } break; } } return output_ptr; } internal static void silk_resampler_private_down_FIR(SilkResamplerState S, Span output, int output_ptr, Span input, int input_ptr, int inLen) { int[] array = new int[S.batchSize + S.FIR_Order]; Arrays.MemCopy(S.sFIR_i32, 0, array, 0, S.FIR_Order); int invRatio_Q = S.invRatio_Q16; int num; while (true) { num = Inlines.silk_min(inLen, S.batchSize); silk_resampler_private_AR2(S.sIIR, 0, array, S.FIR_Order, input, input_ptr, S.Coefs, num); int max_index_Q = Inlines.silk_LSHIFT32(num, 16); output_ptr = silk_resampler_private_down_FIR_INTERPOL(output, output_ptr, array, S.Coefs, 2, S.FIR_Order, S.FIR_Fracs, max_index_Q, invRatio_Q); input_ptr += num; inLen -= num; if (inLen <= 1) { break; } Arrays.MemCopy(array, num, array, 0, S.FIR_Order); } Arrays.MemCopy(array, num, S.sFIR_i32, 0, S.FIR_Order); } internal static int silk_resampler_private_IIR_FIR_INTERPOL(Span output, int output_ptr, short[] buf, int max_index_Q16, int index_increment_Q16) { for (int i = 0; i < max_index_Q16; i += index_increment_Q16) { int num = Inlines.silk_SMULWB(i & 0xFFFF, 12); int num2 = i >> 16; int a = Inlines.silk_SMULBB(buf[num2], Tables.silk_resampler_frac_FIR_12[num, 0]); a = Inlines.silk_SMLABB(a, buf[num2 + 1], Tables.silk_resampler_frac_FIR_12[num, 1]); a = Inlines.silk_SMLABB(a, buf[num2 + 2], Tables.silk_resampler_frac_FIR_12[num, 2]); a = Inlines.silk_SMLABB(a, buf[num2 + 3], Tables.silk_resampler_frac_FIR_12[num, 3]); a = Inlines.silk_SMLABB(a, buf[num2 + 4], Tables.silk_resampler_frac_FIR_12[11 - num, 3]); a = Inlines.silk_SMLABB(a, buf[num2 + 5], Tables.silk_resampler_frac_FIR_12[11 - num, 2]); a = Inlines.silk_SMLABB(a, buf[num2 + 6], Tables.silk_resampler_frac_FIR_12[11 - num, 1]); a = Inlines.silk_SMLABB(a, buf[num2 + 7], Tables.silk_resampler_frac_FIR_12[11 - num, 0]); output[output_ptr++] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 15)); } return output_ptr; } internal static void silk_resampler_private_IIR_FIR(SilkResamplerState S, Span output, int output_ptr, Span input, int input_ptr, int inLen) { short[] array = new short[2 * S.batchSize + 8]; Arrays.MemCopy(S.sFIR_i16, 0, array, 0, 8); int invRatio_Q = S.invRatio_Q16; int num; while (true) { num = Inlines.silk_min(inLen, S.batchSize); silk_resampler_private_up2_HQ(S.sIIR, array, 8, input, input_ptr, num); int max_index_Q = Inlines.silk_LSHIFT32(num, 17); output_ptr = silk_resampler_private_IIR_FIR_INTERPOL(output, output_ptr, array, max_index_Q, invRatio_Q); input_ptr += num; inLen -= num; if (inLen <= 0) { break; } Arrays.MemCopy(array, num << 1, array, 0, 8); } Arrays.MemCopy(array, num << 1, S.sFIR_i16, 0, 8); } internal static void silk_resampler_private_up2_HQ(int[] S, Span output, int output_ptr, Span input, int input_ptr, int len) { for (int i = 0; i < len; i++) { int a = Inlines.silk_LSHIFT(input[input_ptr + i], 10); int b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a, S[0]), Tables.silk_resampler_up2_hq_0[0]); int a2 = Inlines.silk_ADD32(S[0], b); S[0] = Inlines.silk_ADD32(a, b); b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a2, S[1]), Tables.silk_resampler_up2_hq_0[1]); int a3 = Inlines.silk_ADD32(S[1], b); S[1] = Inlines.silk_ADD32(a2, b); int num = Inlines.silk_SUB32(a3, S[2]); b = Inlines.silk_SMLAWB(num, num, Tables.silk_resampler_up2_hq_0[2]); a2 = Inlines.silk_ADD32(S[2], b); S[2] = Inlines.silk_ADD32(a3, b); output[output_ptr + 2 * i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a2, 10)); b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a, S[3]), Tables.silk_resampler_up2_hq_1[0]); a2 = Inlines.silk_ADD32(S[3], b); S[3] = Inlines.silk_ADD32(a, b); b = Inlines.silk_SMULWB(Inlines.silk_SUB32(a2, S[4]), Tables.silk_resampler_up2_hq_1[1]); a3 = Inlines.silk_ADD32(S[4], b); S[4] = Inlines.silk_ADD32(a2, b); int num2 = Inlines.silk_SUB32(a3, S[5]); b = Inlines.silk_SMLAWB(num2, num2, Tables.silk_resampler_up2_hq_1[2]); a2 = Inlines.silk_ADD32(S[5], b); S[5] = Inlines.silk_ADD32(a3, b); output[output_ptr + 2 * i + 1] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a2, 10)); } } } internal static class ResidualEnergy { internal static void silk_residual_energy(int[] nrgs, int[] nrgsQ, short[] x, short[][] a_Q12, int[] gains, int subfr_length, int nb_subfr, int LPC_order) { int num = 0; int num2 = LPC_order + subfr_length; short[] array = new short[2 * num2]; for (int i = 0; i < nb_subfr >> 1; i++) { Filters.silk_LPC_analysis_filter(array, 0, x, num, a_Q12[i], 0, 2 * num2, LPC_order); int num3 = LPC_order; for (int j = 0; j < 2; j++) { SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, array, num3, subfr_length); nrgs[i * 2 + j] = energy; nrgsQ[i * 2 + j] = -shift; num3 += num2; } num += 2 * num2; } for (int i = 0; i < nb_subfr; i++) { int num4 = Inlines.silk_CLZ32(nrgs[i]) - 1; int num5 = Inlines.silk_CLZ32(gains[i]) - 1; int num6 = Inlines.silk_LSHIFT32(gains[i], num5); num6 = Inlines.silk_SMMUL(num6, num6); nrgs[i] = Inlines.silk_SMMUL(num6, Inlines.silk_LSHIFT32(nrgs[i], num4)); nrgsQ[i] += num4 + 2 * num5 - 32 - 32; } } internal static int silk_residual_energy16_covar(short[] c, int c_ptr, int[] wXX, int wXX_ptr, int[] wXx, int wxx, int D, int cQ) { int[] array = new int[D]; int num = 16 - cQ; int a = num; int num2 = 0; for (int i = c_ptr; i < c_ptr + D; i++) { num2 = Inlines.silk_max_32(num2, Inlines.silk_abs(c[i])); } a = Inlines.silk_min_int(a, Inlines.silk_CLZ32(num2) - 17); int a2 = Inlines.silk_max_32(wXX[wXX_ptr], wXX[wXX_ptr + D * D - 1]); a = Inlines.silk_min_int(a, Inlines.silk_CLZ32(Inlines.silk_MUL(D, Inlines.silk_RSHIFT(Inlines.silk_SMULWB(a2, num2), 4))) - 5); a = Inlines.silk_max_int(a, 0); for (int i = 0; i < D; i++) { array[i] = Inlines.silk_LSHIFT(c[c_ptr + i], a); } num -= a; int num3 = 0; for (int i = 0; i < D; i++) { num3 = Inlines.silk_SMLAWB(num3, wXx[i], array[i]); } int a3 = Inlines.silk_RSHIFT(wxx, 1 + num) - num3; int num4 = 0; for (int i = 0; i < D; i++) { num3 = 0; int num5 = wXX_ptr + i * D; for (int j = i + 1; j < D; j++) { num3 = Inlines.silk_SMLAWB(num3, wXX[num5 + j], array[j]); } num3 = Inlines.silk_SMLAWB(num3, Inlines.silk_RSHIFT(wXX[num5 + i], 1), array[i]); num4 = Inlines.silk_SMLAWB(num4, num3, array[i]); } a3 = Inlines.silk_ADD_LSHIFT32(a3, num4, num); if (a3 < 1) { return 1; } if (a3 > Inlines.silk_RSHIFT(int.MaxValue, num + 2)) { return 1073741823; } return Inlines.silk_LSHIFT(a3, num + 1); } } internal static class Schur { internal static int silk_schur(short[] rc_Q15, int[] c, int order) { int[][] array = Arrays.InitTwoDimensionalArray(17, 2); int num = Inlines.silk_CLZ32(c[0]); int i; if (num < 2) { for (i = 0; i < order + 1; i++) { array[i][0] = (array[i][1] = Inlines.silk_RSHIFT(c[i], 1)); } } else if (num > 2) { num -= 2; for (i = 0; i < order + 1; i++) { array[i][0] = (array[i][1] = Inlines.silk_LSHIFT(c[i], num)); } } else { for (i = 0; i < order + 1; i++) { array[i][0] = (array[i][1] = c[i]); } } for (i = 0; i < order; i++) { if (Inlines.silk_abs_int32(array[i + 1][0]) >= array[0][1]) { if (array[i + 1][0] > 0) { rc_Q15[i] = -32440; } else { rc_Q15[i] = 32440; } i++; break; } int a = -Inlines.silk_DIV32_16(array[i + 1][0], Inlines.silk_max_32(Inlines.silk_RSHIFT(array[0][1], 15), 1)); a = Inlines.silk_SAT16(a); rc_Q15[i] = (short)a; for (int j = 0; j < order - i; j++) { int num2 = array[j + i + 1][0]; int num3 = array[j][1]; array[j + i + 1][0] = Inlines.silk_SMLAWB(num2, Inlines.silk_LSHIFT(num3, 1), a); array[j][1] = Inlines.silk_SMLAWB(num3, Inlines.silk_LSHIFT(num2, 1), a); } } for (; i < order; i++) { rc_Q15[i] = 0; } return Inlines.silk_max_32(1, array[0][1]); } internal static int silk_schur64(int[] rc_Q16, int[] c, int order) { int[][] array = Arrays.InitTwoDimensionalArray(17, 2); if (c[0] <= 0) { Arrays.MemSetInt(rc_Q16, 0, order); return 0; } int i; for (i = 0; i < order + 1; i++) { array[i][0] = (array[i][1] = c[i]); } for (i = 0; i < order; i++) { if (Inlines.silk_abs_int32(array[i + 1][0]) >= array[0][1]) { if (array[i + 1][0] > 0) { rc_Q16[i] = -64881; } else { rc_Q16[i] = 64881; } i++; break; } int num = Inlines.silk_DIV32_varQ(-array[i + 1][0], array[0][1], 31); rc_Q16[i] = Inlines.silk_RSHIFT_ROUND(num, 15); for (int j = 0; j < order - i; j++) { int num2 = array[j + i + 1][0]; int num3 = array[j][1]; array[j + i + 1][0] = num2 + Inlines.silk_SMMUL(Inlines.silk_LSHIFT(num3, 1), num); array[j][1] = num3 + Inlines.silk_SMMUL(Inlines.silk_LSHIFT(num2, 1), num); } } for (; i < order; i++) { rc_Q16[i] = 0; } return Inlines.silk_max_32(1, array[0][1]); } } internal static class ShellCoder { internal static void combine_pulses(int[] output, Span input, int input_ptr, int len) { for (int i = 0; i < len; i++) { output[i] = input[input_ptr + 2 * i] + input[input_ptr + 2 * i + 1]; } } internal static void combine_pulses(int[] output, int[] input, int len) { for (int i = 0; i < len; i++) { output[i] = input[2 * i] + input[2 * i + 1]; } } internal static void encode_split(EntropyCoder psRangeEnc, Span encodedData, int p_child1, int p, byte[] shell_table) { if (p > 0) { psRangeEnc.enc_icdf(encodedData, p_child1, shell_table, Tables.silk_shell_code_table_offsets[p], 8u); } } internal static void decode_split(short[] p_child1, int child1_ptr, Span p_child2, int p_child2_ptr, EntropyCoder psRangeDec, ReadOnlySpan encodedData, int p, byte[] shell_table) { if (p > 0) { p_child1[child1_ptr] = (short)psRangeDec.dec_icdf(encodedData, shell_table, Tables.silk_shell_code_table_offsets[p], 8u); p_child2[p_child2_ptr] = (short)(p - p_child1[child1_ptr]); } else { p_child1[child1_ptr] = 0; p_child2[p_child2_ptr] = 0; } } internal static void silk_shell_encoder(EntropyCoder psRangeEnc, Span encodedData, Span pulses0, int pulses0_ptr) { int[] array = new int[8]; int[] array2 = new int[4]; int[] array3 = new int[2]; int[] array4 = new int[1]; combine_pulses(array, pulses0, pulses0_ptr, 8); combine_pulses(array2, array, 4); combine_pulses(array3, array2, 2); combine_pulses(array4, array3, 1); encode_split(psRangeEnc, encodedData, array3[0], array4[0], Tables.silk_shell_code_table3); encode_split(psRangeEnc, encodedData, array2[0], array3[0], Tables.silk_shell_code_table2); encode_split(psRangeEnc, encodedData, array[0], array2[0], Tables.silk_shell_code_table1); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr], array[0], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 2], array[1], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, array[2], array2[1], Tables.silk_shell_code_table1); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 4], array[2], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 6], array[3], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, array2[2], array3[1], Tables.silk_shell_code_table2); encode_split(psRangeEnc, encodedData, array[4], array2[2], Tables.silk_shell_code_table1); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 8], array[4], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 10], array[5], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, array[6], array2[3], Tables.silk_shell_code_table1); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 12], array[6], Tables.silk_shell_code_table0); encode_split(psRangeEnc, encodedData, pulses0[pulses0_ptr + 14], array[7], Tables.silk_shell_code_table0); } internal static void silk_shell_decoder(short[] pulses0, int pulses0_ptr, EntropyCoder psRangeDec, ReadOnlySpan encodedData, int pulses4) { short[] array = new short[8]; short[] array2 = new short[4]; short[] array3 = new short[2]; decode_split(array3, 0, array3, 1, psRangeDec, encodedData, pulses4, Tables.silk_shell_code_table3); decode_split(array2, 0, array2, 1, psRangeDec, encodedData, array3[0], Tables.silk_shell_code_table2); decode_split(array, 0, array, 1, psRangeDec, encodedData, array2[0], Tables.silk_shell_code_table1); decode_split(pulses0, pulses0_ptr, pulses0, pulses0_ptr + 1, psRangeDec, encodedData, array[0], Tables.silk_shell_code_table0); decode_split(pulses0, pulses0_ptr + 2, pulses0, pulses0_ptr + 3, psRangeDec, encodedData, array[1], Tables.silk_shell_code_table0); decode_split(array, 2, array, 3, psRangeDec, encodedData, array2[1], Tables.silk_shell_code_table1); decode_split(pulses0, pulses0_ptr + 4, pulses0, pulses0_ptr + 5, psRangeDec, encodedData, array[2], Tables.silk_shell_code_table0); decode_split(pulses0, pulses0_ptr + 6, pulses0, pulses0_ptr + 7, psRangeDec, encodedData, array[3], Tables.silk_shell_code_table0); decode_split(array2, 2, array2, 3, psRangeDec, encodedData, array3[1], Tables.silk_shell_code_table2); decode_split(array, 4, array, 5, psRangeDec, encodedData, array2[2], Tables.silk_shell_code_table1); decode_split(pulses0, pulses0_ptr + 8, pulses0, pulses0_ptr + 9, psRangeDec, encodedData, array[4], Tables.silk_shell_code_table0); decode_split(pulses0, pulses0_ptr + 10, pulses0, pulses0_ptr + 11, psRangeDec, encodedData, array[5], Tables.silk_shell_code_table0); decode_split(array, 6, array, 7, psRangeDec, encodedData, array2[3], Tables.silk_shell_code_table1); decode_split(pulses0, pulses0_ptr + 12, pulses0, pulses0_ptr + 13, psRangeDec, encodedData, array[6], Tables.silk_shell_code_table0); decode_split(pulses0, pulses0_ptr + 14, pulses0, pulses0_ptr + 15, psRangeDec, encodedData, array[7], Tables.silk_shell_code_table0); } } internal static class Sigmoid { private static readonly int[] sigm_LUT_slope_Q10 = new int[6] { 237, 153, 73, 30, 12, 7 }; private static readonly int[] sigm_LUT_pos_Q15 = new int[6] { 16384, 23955, 28861, 31213, 32178, 32548 }; private static readonly int[] sigm_LUT_neg_Q15 = new int[6] { 16384, 8812, 3906, 1554, 589, 219 }; internal static int silk_sigm_Q15(int in_Q5) { int num; if (in_Q5 < 0) { in_Q5 = -in_Q5; if (in_Q5 >= 192) { return 0; } num = Inlines.silk_RSHIFT(in_Q5, 5); return sigm_LUT_neg_Q15[num] - Inlines.silk_SMULBB(sigm_LUT_slope_Q10[num], in_Q5 & 0x1F); } if (in_Q5 >= 192) { return 32767; } num = Inlines.silk_RSHIFT(in_Q5, 5); return sigm_LUT_pos_Q15[num] + Inlines.silk_SMULBB(sigm_LUT_slope_Q10[num], in_Q5 & 0x1F); } } internal static class SilkConstants { internal const int ENCODER_NUM_CHANNELS = 2; internal const int DECODER_NUM_CHANNELS = 2; internal const int MAX_FRAMES_PER_PACKET = 3; internal const int MIN_TARGET_RATE_BPS = 5000; internal const int MAX_TARGET_RATE_BPS = 80000; internal const int TARGET_RATE_TAB_SZ = 8; internal const int LBRR_NB_MIN_RATE_BPS = 12000; internal const int LBRR_MB_MIN_RATE_BPS = 14000; internal const int LBRR_WB_MIN_RATE_BPS = 16000; internal const int NB_SPEECH_FRAMES_BEFORE_DTX = 10; internal const int MAX_CONSECUTIVE_DTX = 20; internal const int MAX_FS_KHZ = 16; internal const int MAX_API_FS_KHZ = 48; internal const int TYPE_NO_VOICE_ACTIVITY = 0; internal const int TYPE_UNVOICED = 1; internal const int TYPE_VOICED = 2; internal const int CODE_INDEPENDENTLY = 0; internal const int CODE_INDEPENDENTLY_NO_LTP_SCALING = 1; internal const int CODE_CONDITIONALLY = 2; internal const int STEREO_QUANT_TAB_SIZE = 16; internal const int STEREO_QUANT_SUB_STEPS = 5; internal const int STEREO_INTERP_LEN_MS = 8; internal const float STEREO_RATIO_SMOOTH_COEF = 0.01f; internal const int PITCH_EST_MIN_LAG_MS = 2; internal const int PITCH_EST_MAX_LAG_MS = 18; internal const int MAX_NB_SUBFR = 4; internal const int LTP_MEM_LENGTH_MS = 20; internal const int SUB_FRAME_LENGTH_MS = 5; internal const int MAX_SUB_FRAME_LENGTH = 80; internal const int MAX_FRAME_LENGTH_MS = 20; internal const int MAX_FRAME_LENGTH = 320; internal const int LA_PITCH_MS = 2; internal const int LA_PITCH_MAX = 32; internal const int MAX_FIND_PITCH_LPC_ORDER = 16; internal const int FIND_PITCH_LPC_WIN_MS = 24; internal const int FIND_PITCH_LPC_WIN_MS_2_SF = 14; internal const int FIND_PITCH_LPC_WIN_MAX = 384; internal const int LA_SHAPE_MS = 5; internal const int LA_SHAPE_MAX = 80; internal const int SHAPE_LPC_WIN_MAX = 240; internal const int MIN_QGAIN_DB = 2; internal const int MAX_QGAIN_DB = 88; internal const int N_LEVELS_QGAIN = 64; internal const int MAX_DELTA_GAIN_QUANT = 36; internal const int MIN_DELTA_GAIN_QUANT = -4; internal const short OFFSET_VL_Q10 = 32; internal const short OFFSET_VH_Q10 = 100; internal const short OFFSET_UVL_Q10 = 100; internal const short OFFSET_UVH_Q10 = 240; internal const int QUANT_LEVEL_ADJUST_Q10 = 80; internal const int MAX_LPC_STABILIZE_ITERATIONS = 16; internal const float MAX_PREDICTION_POWER_GAIN = 10000f; internal const float MAX_PREDICTION_POWER_GAIN_AFTER_RESET = 100f; internal const int SILK_MAX_ORDER_LPC = 16; internal const int MAX_LPC_ORDER = 16; internal const int MIN_LPC_ORDER = 10; internal const int LTP_ORDER = 5; internal const int NB_LTP_CBKS = 3; internal const int USE_HARM_SHAPING = 1; internal const int MAX_SHAPE_LPC_ORDER = 16; internal const int HARM_SHAPE_FIR_TAPS = 3; internal const int MAX_DEL_DEC_STATES = 4; internal const int LTP_BUF_LENGTH = 512; internal const int LTP_MASK = 511; internal const int DECISION_DELAY = 32; internal const int DECISION_DELAY_MASK = 31; internal const int SHELL_CODEC_FRAME_LENGTH = 16; internal const int LOG2_SHELL_CODEC_FRAME_LENGTH = 4; internal const int MAX_NB_SHELL_BLOCKS = 20; internal const int N_RATE_LEVELS = 10; internal const int SILK_MAX_PULSES = 16; internal const int MAX_MATRIX_SIZE = 16; internal static readonly int NSQ_LPC_BUF_LENGTH = Math.Max(16, 32); internal const int VAD_N_BANDS = 4; internal const int VAD_INTERNAL_SUBFRAMES_LOG2 = 2; internal const int VAD_INTERNAL_SUBFRAMES = 4; internal const int VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 = 1024; internal const int VAD_NOISE_LEVELS_BIAS = 50; internal const int VAD_NEGATIVE_OFFSET_Q5 = 128; internal const int VAD_SNR_FACTOR_Q16 = 45000; internal const int VAD_SNR_SMOOTH_COEF_Q18 = 4096; internal const int LSF_COS_TAB_SZ = 128; internal const int NLSF_W_Q = 2; internal const int NLSF_VQ_MAX_VECTORS = 32; internal const int NLSF_VQ_MAX_SURVIVORS = 32; internal const int NLSF_QUANT_MAX_AMPLITUDE = 4; internal const int NLSF_QUANT_MAX_AMPLITUDE_EXT = 10; internal const float NLSF_QUANT_LEVEL_ADJ = 0.1f; internal const int NLSF_QUANT_DEL_DEC_STATES_LOG2 = 2; internal const int NLSF_QUANT_DEL_DEC_STATES = 4; internal const int TRANSITION_TIME_MS = 5120; internal const int TRANSITION_NB = 3; internal const int TRANSITION_NA = 2; internal const int TRANSITION_INT_NUM = 5; internal const int TRANSITION_FRAMES = 256; internal const int TRANSITION_INT_STEPS = 64; internal const int BWE_AFTER_LOSS_Q16 = 63570; internal const int CNG_BUF_MASK_MAX = 255; internal const int CNG_GAIN_SMTH_Q16 = 4634; internal const int CNG_NLSF_SMTH_Q16 = 16348; internal const int PE_MAX_FS_KHZ = 16; internal const int PE_MAX_NB_SUBFR = 4; internal const int PE_SUBFR_LENGTH_MS = 5; internal const int PE_LTP_MEM_LENGTH_MS = 20; internal const int PE_MAX_FRAME_LENGTH_MS = 40; internal const int PE_MAX_FRAME_LENGTH = 640; internal const int PE_MAX_FRAME_LENGTH_ST_1 = 160; internal const int PE_MAX_FRAME_LENGTH_ST_2 = 320; internal const int PE_MAX_LAG_MS = 18; internal const int PE_MIN_LAG_MS = 2; internal const int PE_MAX_LAG = 288; internal const int PE_MIN_LAG = 32; internal const int PE_D_SRCH_LENGTH = 24; internal const int PE_NB_STAGE3_LAGS = 5; internal const int PE_NB_CBKS_STAGE2 = 3; internal const int PE_NB_CBKS_STAGE2_EXT = 11; internal const int PE_NB_CBKS_STAGE3_MAX = 34; internal const int PE_NB_CBKS_STAGE3_MID = 24; internal const int PE_NB_CBKS_STAGE3_MIN = 16; internal const int PE_NB_CBKS_STAGE3_10MS = 12; internal const int PE_NB_CBKS_STAGE2_10MS = 3; internal const float PE_SHORTLAG_BIAS = 0.2f; internal const float PE_PREVLAG_BIAS = 0.2f; internal const float PE_FLATCONTOUR_BIAS = 0.05f; internal const int SILK_PE_MIN_COMPLEX = 0; internal const int SILK_PE_MID_COMPLEX = 1; internal const int SILK_PE_MAX_COMPLEX = 2; internal const float BWE_COEF = 0.99f; internal const int V_PITCH_GAIN_START_MIN_Q14 = 11469; internal const int V_PITCH_GAIN_START_MAX_Q14 = 15565; internal const int MAX_PITCH_LAG_MS = 18; internal const int RAND_BUF_SIZE = 128; internal const int RAND_BUF_MASK = 127; internal const int LOG2_INV_LPC_GAIN_HIGH_THRES = 3; internal const int LOG2_INV_LPC_GAIN_LOW_THRES = 8; internal const int PITCH_DRIFT_FAC_Q16 = 655; internal const int SILK_RESAMPLER_MAX_FIR_ORDER = 36; internal const int SILK_RESAMPLER_MAX_IIR_ORDER = 6; internal const int RESAMPLER_DOWN_ORDER_FIR0 = 18; internal const int RESAMPLER_DOWN_ORDER_FIR1 = 24; internal const int RESAMPLER_DOWN_ORDER_FIR2 = 36; internal const int RESAMPLER_ORDER_FIR_12 = 8; internal const int RESAMPLER_MAX_BATCH_SIZE_MS = 10; internal const int RESAMPLER_MAX_FS_KHZ = 48; internal const int RESAMPLER_MAX_BATCH_SIZE_IN = 480; internal const int SILK_MAX_FRAMES_PER_PACKET = 3; } internal static class Sort { internal static void silk_insertion_sort_increasing(int[] a, int[] idx, int L, int K) { for (int i = 0; i < K; i++) { idx[i] = i; } for (int i = 1; i < K; i++) { int num = a[i]; int num2 = i - 1; while (num2 >= 0 && num < a[num2]) { a[num2 + 1] = a[num2]; idx[num2 + 1] = idx[num2]; num2--; } a[num2 + 1] = num; idx[num2 + 1] = i; } for (int i = K; i < L; i++) { int num = a[i]; if (num < a[K - 1]) { int num2 = K - 2; while (num2 >= 0 && num < a[num2]) { a[num2 + 1] = a[num2]; idx[num2 + 1] = idx[num2]; num2--; } a[num2 + 1] = num; idx[num2 + 1] = i; } } } internal static void silk_insertion_sort_increasing_all_values_int16(short[] a, int L) { for (int i = 1; i < L; i++) { short num = a[i]; int num2 = i - 1; while (num2 >= 0 && num < a[num2]) { a[num2 + 1] = a[num2]; num2--; } a[num2 + 1] = num; } } internal static void silk_insertion_sort_decreasing_int16(short[] a, int[] idx, int L, int K) { for (int i = 0; i < K; i++) { idx[i] = i; } for (int i = 1; i < K; i++) { short num = a[i]; int num2 = i - 1; while (num2 >= 0 && num > a[num2]) { a[num2 + 1] = a[num2]; idx[num2 + 1] = idx[num2]; num2--; } a[num2 + 1] = num; idx[num2 + 1] = i; } for (int i = K; i < L; i++) { short num = a[i]; if (num > a[K - 1]) { int num2 = K - 2; while (num2 >= 0 && num > a[num2]) { a[num2 + 1] = a[num2]; idx[num2 + 1] = idx[num2]; num2--; } a[num2 + 1] = num; idx[num2 + 1] = i; } } } } internal static class Stereo { internal static void silk_stereo_decode_pred(EntropyCoder psRangeDec, ReadOnlySpan encodedData, int[] pred_Q13) { int[][] array = Arrays.InitTwoDimensionalArray(2, 3); int num = psRangeDec.dec_icdf(encodedData, Tables.silk_stereo_pred_joint_iCDF, 8u); array[0][2] = Inlines.silk_DIV32_16(num, 5); array[1][2] = num - 5 * array[0][2]; for (num = 0; num < 2; num++) { array[num][0] = psRangeDec.dec_icdf(encodedData, Tables.silk_uniform3_iCDF, 8u); array[num][1] = psRangeDec.dec_icdf(encodedData, Tables.silk_uniform5_iCDF, 8u); } for (num = 0; num < 2; num++) { array[num][0] += 3 * array[num][2]; int num2 = Tables.silk_stereo_pred_quant_Q13[array[num][0]]; int b = Inlines.silk_SMULWB(Tables.silk_stereo_pred_quant_Q13[array[num][0] + 1] - num2, 6554); pred_Q13[num] = Inlines.silk_SMLABB(num2, b, 2 * array[num][1] + 1); } pred_Q13[0] -= pred_Q13[1]; } internal static void silk_stereo_decode_mid_only(EntropyCoder psRangeDec, ReadOnlySpan encodedData, BoxedValueInt decode_only_mid) { decode_only_mid.Val = psRangeDec.dec_icdf(encodedData, Tables.silk_stereo_only_code_mid_iCDF, 8u); } internal static void silk_stereo_encode_pred(EntropyCoder psRangeEnc, Span encodedData, sbyte[][] ix) { int s = 5 * ix[0][2] + ix[1][2]; psRangeEnc.enc_icdf(encodedData, s, Tables.silk_stereo_pred_joint_iCDF, 8u); for (s = 0; s < 2; s++) { psRangeEnc.enc_icdf(encodedData, ix[s][0], Tables.silk_uniform3_iCDF, 8u); psRangeEnc.enc_icdf(encodedData, ix[s][1], Tables.silk_uniform5_iCDF, 8u); } } internal static void silk_stereo_encode_mid_only(EntropyCoder psRangeEnc, Span encodedData, sbyte mid_only_flag) { psRangeEnc.enc_icdf(encodedData, mid_only_flag, Tables.silk_stereo_only_code_mid_iCDF, 8u); } internal static int silk_stereo_find_predictor(BoxedValueInt ratio_Q14, short[] x, short[] y, Span mid_res_amp_Q0, int mid_res_amp_Q0_ptr, int length, int smooth_coef_Q16) { SumSqrShift.silk_sum_sqr_shift(out var energy, out var shift, x, length); SumSqrShift.silk_sum_sqr_shift(out var energy2, out var shift2, y, length); int num = Inlines.silk_max_int(shift, shift2); num += num & 1; energy2 = Inlines.silk_RSHIFT32(energy2, num - shift2); energy = Inlines.silk_RSHIFT32(energy, num - shift); energy = Inlines.silk_max_int(energy, 1); int a = Inlines.silk_inner_prod_aligned_scale(x, y, num, length); int a2 = Inlines.silk_DIV32_varQ(a, energy, 13); a2 = Inlines.silk_LIMIT(a2, -16384, 16384); int num2 = Inlines.silk_SMULWB(a2, a2); smooth_coef_Q16 = Inlines.silk_max_int(smooth_coef_Q16, Inlines.silk_abs(num2)); num = Inlines.silk_RSHIFT(num, 1); mid_res_amp_Q0[mid_res_amp_Q0_ptr] = Inlines.silk_SMLAWB(mid_res_amp_Q0[mid_res_amp_Q0_ptr], Inlines.silk_LSHIFT(Inlines.silk_SQRT_APPROX(energy), num) - mid_res_amp_Q0[mid_res_amp_Q0_ptr], smooth_coef_Q16); energy2 = Inlines.silk_SUB_LSHIFT32(energy2, Inlines.silk_SMULWB(a, a2), 4); energy2 = Inlines.silk_ADD_LSHIFT32(energy2, Inlines.silk_SMULWB(energy, num2), 6); mid_res_amp_Q0[mid_res_amp_Q0_ptr + 1] = Inlines.silk_SMLAWB(mid_res_amp_Q0[mid_res_amp_Q0_ptr + 1], Inlines.silk_LSHIFT(Inlines.silk_SQRT_APPROX(energy2), num) - mid_res_amp_Q0[mid_res_amp_Q0_ptr + 1], smooth_coef_Q16); ratio_Q14.Val = Inlines.silk_DIV32_varQ(mid_res_amp_Q0[mid_res_amp_Q0_ptr + 1], Inlines.silk_max(mid_res_amp_Q0[mid_res_amp_Q0_ptr], 1), 14); ratio_Q14.Val = Inlines.silk_LIMIT(ratio_Q14.Val, 0, 32767); return a2; } internal static void silk_stereo_LR_to_MS(StereoEncodeState state, Span x1, int x1_ptr, Span x2, int x2_ptr, sbyte[][] ix, BoxedValueSbyte mid_only_flag, int[] mid_side_rates_bps, int total_rate_bps, int prev_speech_act_Q8, int toMono, int fs_kHz, int frame_length) { int[] array = new int[2]; BoxedValueInt boxedValueInt = new BoxedValueInt(); BoxedValueInt boxedValueInt2 = new BoxedValueInt(); int num = x1_ptr - 2; short[] array2 = new short[frame_length + 2]; for (int i = 0; i < frame_length + 2; i++) { int a = x1[x1_ptr + i - 2] + x2[x2_ptr + i - 2]; int a2 = x1[x1_ptr + i - 2] - x2[x2_ptr + i - 2]; x1[num + i] = (short)Inlines.silk_RSHIFT_ROUND(a, 1); array2[i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a2, 1)); } MemoryExtensions.AsSpan(state.sMid, 0, 2).CopyTo(x1.Slice(num)); Arrays.MemCopy(state.sSide, 0, array2, 0, 2); x1.Slice(num + frame_length, 2).CopyTo(state.sMid); Arrays.MemCopy(array2, frame_length, state.sSide, 0, 2); short[] array3 = new short[frame_length]; short[] array4 = new short[frame_length]; for (int i = 0; i < frame_length; i++) { int a = Inlines.silk_RSHIFT_ROUND(Inlines.silk_ADD_LSHIFT32(x1[num + i] + x1[num + i + 2], x1[num + i + 1], 1), 2); array3[i] = (short)a; array4[i] = (short)(x1[num + i + 1] - a); } short[] array5 = new short[frame_length]; short[] array6 = new short[frame_length]; for (int i = 0; i < frame_length; i++) { int a = Inlines.silk_RSHIFT_ROUND(Inlines.silk_ADD_LSHIFT32(array2[i] + array2[i + 2], array2[i + 1], 1), 2); array5[i] = (short)a; array6[i] = (short)(array2[i + 1] - a); } int num2 = ((frame_length == 10 * fs_kHz) ? 1 : 0); int b = ((num2 != 0) ? 328 : 655); b = Inlines.silk_SMULWB(Inlines.silk_SMULBB(prev_speech_act_Q8, prev_speech_act_Q8), b); array[0] = silk_stereo_find_predictor(boxedValueInt, array3, array5, state.mid_side_amp_Q0, 0, frame_length, b); array[1] = silk_stereo_find_predictor(boxedValueInt2, array4, array6, state.mid_side_amp_Q0, 2, frame_length, b); int a3 = Inlines.silk_SMLABB(boxedValueInt2.Val, boxedValueInt.Val, 3); a3 = Inlines.silk_min(a3, 65536); total_rate_bps -= ((num2 != 0) ? 1200 : 600); if (total_rate_bps < 1) { total_rate_bps = 1; } int num3 = Inlines.silk_SMLABB(2000, fs_kHz, 900); int num4 = Inlines.silk_MUL(3, a3); mid_side_rates_bps[0] = Inlines.silk_DIV32_varQ(total_rate_bps, 851968 + num4, 19); int a4; if (mid_side_rates_bps[0] < num3) { mid_side_rates_bps[0] = num3; mid_side_rates_bps[1] = total_rate_bps - mid_side_rates_bps[0]; a4 = Inlines.silk_DIV32_varQ(Inlines.silk_LSHIFT(mid_side_rates_bps[1], 1) - num3, Inlines.silk_SMULWB(65536 + num4, num3), 16); a4 = Inlines.silk_LIMIT(a4, 0, 16384); } else { mid_side_rates_bps[1] = total_rate_bps - mid_side_rates_bps[0]; a4 = 16384; } state.smth_width_Q14 = (short)Inlines.silk_SMLAWB(state.smth_width_Q14, a4 - state.smth_width_Q14, b); mid_only_flag.Val = 0; if (toMono != 0) { a4 = 0; array[0] = 0; array[1] = 0; silk_stereo_quant_pred(array, ix); } else if (state.width_prev_Q14 == 0 && (8 * total_rate_bps < 13 * num3 || Inlines.silk_SMULWB(a3, state.smth_width_Q14) < 819)) { array[0] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[0]), 14); array[1] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[1]), 14); silk_stereo_quant_pred(array, ix); a4 = 0; array[0] = 0; array[1] = 0; mid_side_rates_bps[0] = total_rate_bps; mid_side_rates_bps[1] = 0; mid_only_flag.Val = 1; } else if (state.width_prev_Q14 != 0 && (8 * total_rate_bps < 11 * num3 || Inlines.silk_SMULWB(a3, state.smth_width_Q14) < 328)) { array[0] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[0]), 14); array[1] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[1]), 14); silk_stereo_quant_pred(array, ix); a4 = 0; array[0] = 0; array[1] = 0; } else if (state.smth_width_Q14 > 15565) { silk_stereo_quant_pred(array, ix); a4 = 16384; } else { array[0] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[0]), 14); array[1] = Inlines.silk_RSHIFT(Inlines.silk_SMULBB(state.smth_width_Q14, array[1]), 14); silk_stereo_quant_pred(array, ix); a4 = state.smth_width_Q14; } if (mid_only_flag.Val == 1) { state.silent_side_len += (short)(frame_length - 8 * fs_kHz); if (state.silent_side_len < 5 * fs_kHz) { mid_only_flag.Val = 0; } else { state.silent_side_len = 10000; } } else { state.silent_side_len = 0; } if (mid_only_flag.Val == 0 && mid_side_rates_bps[1] < 1) { mid_side_rates_bps[1] = 1; mid_side_rates_bps[0] = Inlines.silk_max_int(1, total_rate_bps - mid_side_rates_bps[1]); } int num5 = -state.pred_prev_Q13[0]; int num6 = -state.pred_prev_Q13[1]; int num7 = Inlines.silk_LSHIFT(state.width_prev_Q14, 10); int b2 = Inlines.silk_DIV32_16(65536, 8 * fs_kHz); int num8 = -Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULBB(array[0] - state.pred_prev_Q13[0], b2), 16); int num9 = -Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULBB(array[1] - state.pred_prev_Q13[1], b2), 16); int num10 = Inlines.silk_LSHIFT(Inlines.silk_SMULWB(a4 - state.width_prev_Q14, b2), 10); for (int i = 0; i < 8 * fs_kHz; i++) { num5 += num8; num6 += num9; num7 += num10; int a = Inlines.silk_LSHIFT(Inlines.silk_ADD_LSHIFT(x1[num + i] + x1[num + i + 2], x1[num + i + 1], 1), 9); a = Inlines.silk_SMLAWB(Inlines.silk_SMULWB(num7, array2[i + 1]), a, num5); a = Inlines.silk_SMLAWB(a, Inlines.silk_LSHIFT(x1[num + i + 1], 11), num6); x2[x2_ptr + i - 1] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 8)); } num5 = -array[0]; num6 = -array[1]; num7 = Inlines.silk_LSHIFT(a4, 10); for (int i = 8 * fs_kHz; i < frame_length; i++) { int a = Inlines.silk_LSHIFT(Inlines.silk_ADD_LSHIFT(x1[num + i] + x1[num + i + 2], x1[num + i + 1], 1), 9); a = Inlines.silk_SMLAWB(Inlines.silk_SMULWB(num7, array2[i + 1]), a, num5); a = Inlines.silk_SMLAWB(a, Inlines.silk_LSHIFT(x1[num + i + 1], 11), num6); x2[x2_ptr + i - 1] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(a, 8)); } state.pred_prev_Q13[0] = (short)array[0]; state.pred_prev_Q13[1] = (short)array[1]; state.width_prev_Q14 = (short)a4; } internal static void silk_stereo_MS_to_LR(StereoDecodeState state, Span x1, int x1_ptr, Span x2, int x2_ptr, int[] pred_Q13, int fs_kHz, int frame_length) { MemoryExtensions.AsSpan(state.sMid, 0, 2).CopyTo(x1.Slice(x1_ptr)); MemoryExtensions.AsSpan(state.sSide, 0, 2).CopyTo(x2.Slice(x2_ptr)); x1.Slice(x1_ptr + frame_length, 2).CopyTo(state.sMid); x2.Slice(x2_ptr + frame_length, 2).CopyTo(state.sSide); int num = state.pred_prev_Q13[0]; int num2 = state.pred_prev_Q13[1]; int b = Inlines.silk_DIV32_16(65536, 8 * fs_kHz); int num3 = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULBB(pred_Q13[0] - state.pred_prev_Q13[0], b), 16); int num4 = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULBB(pred_Q13[1] - state.pred_prev_Q13[1], b), 16); for (int i = 0; i < 8 * fs_kHz; i++) { num += num3; num2 += num4; int b2 = Inlines.silk_LSHIFT(Inlines.silk_ADD_LSHIFT(x1[x1_ptr + i] + x1[x1_ptr + i + 2], x1[x1_ptr + i + 1], 1), 9); b2 = Inlines.silk_SMLAWB(Inlines.silk_LSHIFT(x2[x2_ptr + i + 1], 8), b2, num); b2 = Inlines.silk_SMLAWB(b2, Inlines.silk_LSHIFT(x1[x1_ptr + i + 1], 11), num2); x2[x2_ptr + i + 1] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(b2, 8)); } num = pred_Q13[0]; num2 = pred_Q13[1]; for (int i = 8 * fs_kHz; i < frame_length; i++) { int b2 = Inlines.silk_LSHIFT(Inlines.silk_ADD_LSHIFT(x1[x1_ptr + i] + x1[x1_ptr + i + 2], x1[x1_ptr + i + 1], 1), 9); b2 = Inlines.silk_SMLAWB(Inlines.silk_LSHIFT(x2[x2_ptr + i + 1], 8), b2, num); b2 = Inlines.silk_SMLAWB(b2, Inlines.silk_LSHIFT(x1[x1_ptr + i + 1], 11), num2); x2[x2_ptr + i + 1] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(b2, 8)); } state.pred_prev_Q13[0] = (short)pred_Q13[0]; state.pred_prev_Q13[1] = (short)pred_Q13[1]; for (int i = 0; i < frame_length; i++) { int b2 = x1[x1_ptr + i + 1] + x2[x2_ptr + i + 1]; int a = x1[x1_ptr + i + 1] - x2[x2_ptr + i + 1]; x1[x1_ptr + i + 1] = (short)Inlines.silk_SAT16(b2); x2[x2_ptr + i + 1] = (short)Inlines.silk_SAT16(a); } } internal static void silk_stereo_quant_pred(int[] pred_Q13, sbyte[][] ix) { int num = 0; Arrays.MemSetSbyte(ix[0], 0, 3); Arrays.MemSetSbyte(ix[1], 0, 3); for (int i = 0; i < 2; i++) { int num2 = int.MaxValue; sbyte b = 0; while (b < 15) { int num3 = Tables.silk_stereo_pred_quant_Q13[b]; int b2 = Inlines.silk_SMULWB(Tables.silk_stereo_pred_quant_Q13[b + 1] - num3, 6554); for (sbyte b3 = 0; b3 < 5; b3++) { int num4 = Inlines.silk_SMLABB(num3, b2, 2 * b3 + 1); int num5 = Inlines.silk_abs(pred_Q13[i] - num4); if (num5 >= num2) { goto end_IL_0090; } num2 = num5; num = num4; ix[i][0] = b; ix[i][1] = b3; } b++; continue; end_IL_0090: break; } ix[i][2] = (sbyte)Inlines.silk_DIV32_16(ix[i][0], 3); ix[i][0] = (sbyte)(ix[i][0] - (sbyte)(ix[i][2] * 3)); pred_Q13[i] = num; } pred_Q13[0] -= pred_Q13[1]; } } internal static class SumSqrShift { internal static void silk_sum_sqr_shift(out int energy, out int shift, Span x, int x_ptr, int len) { int num = 0; int num2 = 0; len--; int i; for (i = 0; i < len; i += 2) { num = Inlines.silk_SMLABB_ovflw(num, x[x_ptr + i], x[x_ptr + i]); num = Inlines.silk_SMLABB_ovflw(num, x[x_ptr + i + 1], x[x_ptr + i + 1]); if (num < 0) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 = 2; i += 2; break; } } for (; i < len; i += 2) { int a = Inlines.silk_SMULBB(x[x_ptr + i], x[x_ptr + i]); a = Inlines.silk_SMLABB_ovflw(a, x[x_ptr + i + 1], x[x_ptr + i + 1]); num = (int)Inlines.silk_ADD_RSHIFT_uint((uint)num, (uint)a, num2); if (num < 0) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 += 2; } } if (i == len) { int a = Inlines.silk_SMULBB(x[x_ptr + i], x[x_ptr + i]); num = (int)Inlines.silk_ADD_RSHIFT_uint((uint)num, (uint)a, num2); } if ((num & 0xC0000000u) != 0L) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 += 2; } shift = num2; energy = num; } internal static void silk_sum_sqr_shift(out int energy, out int shift, short[] x, int len) { int num = 0; int num2 = 0; len--; int i; for (i = 0; i < len; i += 2) { num = Inlines.silk_SMLABB_ovflw(num, x[i], x[i]); num = Inlines.silk_SMLABB_ovflw(num, x[i + 1], x[i + 1]); if (num < 0) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 = 2; i += 2; break; } } for (; i < len; i += 2) { int a = Inlines.silk_SMULBB(x[i], x[i]); a = Inlines.silk_SMLABB_ovflw(a, x[i + 1], x[i + 1]); num = (int)Inlines.silk_ADD_RSHIFT_uint((uint)num, (uint)a, num2); if (num < 0) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 += 2; } } if (i == len) { int a = Inlines.silk_SMULBB(x[i], x[i]); num = (int)Inlines.silk_ADD_RSHIFT_uint((uint)num, (uint)a, num2); } if ((num & 0xC0000000u) != 0L) { num = (int)Inlines.silk_RSHIFT_uint((uint)num, 2); num2 += 2; } shift = num2; energy = num; } } internal static class Tables { internal static readonly short[] silk_LSFCosTab_Q12 = new short[129] { 8192, 8190, 8182, 8170, 8152, 8130, 8104, 8072, 8034, 7994, 7946, 7896, 7840, 7778, 7714, 7644, 7568, 7490, 7406, 7318, 7226, 7128, 7026, 6922, 6812, 6698, 6580, 6458, 6332, 6204, 6070, 5934, 5792, 5648, 5502, 5352, 5198, 5040, 4880, 4718, 4552, 4382, 4212, 4038, 3862, 3684, 3502, 3320, 3136, 2948, 2760, 2570, 2378, 2186, 1990, 1794, 1598, 1400, 1202, 1002, 802, 602, 402, 202, 0, -202, -402, -602, -802, -1002, -1202, -1400, -1598, -1794, -1990, -2186, -2378, -2570, -2760, -2948, -3136, -3320, -3502, -3684, -3862, -4038, -4212, -4382, -4552, -4718, -4880, -5040, -5198, -5352, -5502, -5648, -5792, -5934, -6070, -6204, -6332, -6458, -6580, -6698, -6812, -6922, -7026, -7128, -7226, -7318, -7406, -7490, -7568, -7644, -7714, -7778, -7840, -7896, -7946, -7994, -8034, -8072, -8104, -8130, -8152, -8170, -8182, -8190, -8192 }; internal static readonly byte[][] silk_gain_iCDF = new byte[3][] { new byte[8] { 224, 112, 44, 15, 3, 2, 1, 0 }, new byte[8] { 254, 237, 192, 132, 70, 23, 4, 0 }, new byte[8] { 255, 252, 226, 155, 61, 11, 2, 0 } }; internal static readonly byte[] silk_delta_gain_iCDF = new byte[41] { 250, 245, 234, 203, 71, 50, 42, 38, 35, 33, 31, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; internal static readonly byte[] silk_LTP_per_index_iCDF = new byte[3] { 179, 99, 0 }; internal static readonly byte[] silk_LTP_gain_iCDF_0 = new byte[8] { 71, 56, 43, 30, 21, 12, 6, 0 }; internal static readonly byte[] silk_LTP_gain_iCDF_1 = new byte[16] { 199, 165, 144, 124, 109, 96, 84, 71, 61, 51, 42, 32, 23, 15, 8, 0 }; internal static readonly byte[] silk_LTP_gain_iCDF_2 = new byte[32] { 241, 225, 211, 199, 187, 175, 164, 153, 142, 132, 123, 114, 105, 96, 88, 80, 72, 64, 57, 50, 44, 38, 33, 29, 24, 20, 16, 12, 9, 5, 2, 0 }; internal static readonly short silk_LTP_gain_middle_avg_RD_Q14 = 12304; internal static readonly byte[] silk_LTP_gain_BITS_Q5_0 = new byte[8] { 15, 131, 138, 138, 155, 155, 173, 173 }; internal static readonly byte[] silk_LTP_gain_BITS_Q5_1 = new byte[16] { 69, 93, 115, 118, 131, 138, 141, 138, 150, 150, 155, 150, 155, 160, 166, 160 }; internal static readonly byte[] silk_LTP_gain_BITS_Q5_2 = new byte[32] { 131, 128, 134, 141, 141, 141, 145, 145, 145, 150, 155, 155, 155, 155, 160, 160, 160, 160, 166, 166, 173, 173, 182, 192, 182, 192, 192, 192, 205, 192, 205, 224 }; internal static readonly byte[][] silk_LTP_gain_iCDF_ptrs = new byte[3][] { silk_LTP_gain_iCDF_0, silk_LTP_gain_iCDF_1, silk_LTP_gain_iCDF_2 }; internal static readonly byte[][] silk_LTP_gain_BITS_Q5_ptrs = new byte[3][] { silk_LTP_gain_BITS_Q5_0, silk_LTP_gain_BITS_Q5_1, silk_LTP_gain_BITS_Q5_2 }; internal static readonly sbyte[][] silk_LTP_gain_vq_0 = new sbyte[8][] { new sbyte[5] { 4, 6, 24, 7, 5 }, new sbyte[5] { 0, 0, 2, 0, 0 }, new sbyte[5] { 12, 28, 41, 13, -4 }, new sbyte[5] { -9, 15, 42, 25, 14 }, new sbyte[5] { 1, -2, 62, 41, -9 }, new sbyte[5] { -10, 37, 65, -4, 3 }, new sbyte[5] { -6, 4, 66, 7, -8 }, new sbyte[5] { 16, 14, 38, -3, 33 } }; internal static readonly sbyte[][] silk_LTP_gain_vq_1 = new sbyte[16][] { new sbyte[5] { 13, 22, 39, 23, 12 }, new sbyte[5] { -1, 36, 64, 27, -6 }, new sbyte[5] { -7, 10, 55, 43, 17 }, new sbyte[5] { 1, 1, 8, 1, 1 }, new sbyte[5] { 6, -11, 74, 53, -9 }, new sbyte[5] { -12, 55, 76, -12, 8 }, new sbyte[5] { -3, 3, 93, 27, -4 }, new sbyte[5] { 26, 39, 59, 3, -8 }, new sbyte[5] { 2, 0, 77, 11, 9 }, new sbyte[5] { -8, 22, 44, -6, 7 }, new sbyte[5] { 40, 9, 26, 3, 9 }, new sbyte[5] { -7, 20, 101, -7, 4 }, new sbyte[5] { 3, -8, 42, 26, 0 }, new sbyte[5] { -15, 33, 68, 2, 23 }, new sbyte[5] { -2, 55, 46, -2, 15 }, new sbyte[5] { 3, -1, 21, 16, 41 } }; internal static readonly sbyte[][] silk_LTP_gain_vq_2 = new sbyte[32][] { new sbyte[5] { -6, 27, 61, 39, 5 }, new sbyte[5] { -11, 42, 88, 4, 1 }, new sbyte[5] { -2, 60, 65, 6, -4 }, new sbyte[5] { -1, -5, 73, 56, 1 }, new sbyte[5] { -9, 19, 94, 29, -9 }, new sbyte[5] { 0, 12, 99, 6, 4 }, new sbyte[5] { 8, -19, 102, 46, -13 }, new sbyte[5] { 3, 2, 13, 3, 2 }, new sbyte[5] { 9, -21, 84, 72, -18 }, new sbyte[5] { -11, 46, 104, -22, 8 }, new sbyte[5] { 18, 38, 48, 23, 0 }, new sbyte[5] { -16, 70, 83, -21, 11 }, new sbyte[5] { 5, -11, 117, 22, -8 }, new sbyte[5] { -6, 23, 117, -12, 3 }, new sbyte[5] { 3, -8, 95, 28, 4 }, new sbyte[5] { -10, 15, 77, 60, -15 }, new sbyte[5] { -1, 4, 124, 2, -4 }, new sbyte[5] { 3, 38, 84, 24, -25 }, new sbyte[5] { 2, 13, 42, 13, 31 }, new sbyte[5] { 21, -4, 56, 46, -1 }, new sbyte[5] { -1, 35, 79, -13, 19 }, new sbyte[5] { -7, 65, 88, -9, -14 }, new sbyte[5] { 20, 4, 81, 49, -29 }, new sbyte[5] { 20, 0, 75, 3, -17 }, new sbyte[5] { 5, -9, 44, 92, -8 }, new sbyte[5] { 1, -3, 22, 69, 31 }, new sbyte[5] { -6, 95, 41, -12, 5 }, new sbyte[5] { 39, 67, 16, -4, 1 }, new sbyte[5] { 0, -6, 120, 55, -36 }, new sbyte[5] { -13, 44, 122, 4, -24 }, new sbyte[5] { 81, 5, 11, 3, 7 }, new sbyte[5] { 2, 0, 9, 10, 88 } }; internal static readonly sbyte[][][] silk_LTP_vq_ptrs_Q7 = new sbyte[3][][] { silk_LTP_gain_vq_0, silk_LTP_gain_vq_1, silk_LTP_gain_vq_2 }; internal static readonly byte[] silk_LTP_gain_vq_0_gain = new byte[8] { 46, 2, 90, 87, 93, 91, 82, 98 }; internal static readonly byte[] silk_LTP_gain_vq_1_gain = new byte[16] { 109, 120, 118, 12, 113, 115, 117, 119, 99, 59, 87, 111, 63, 111, 112, 80 }; internal static readonly byte[] silk_LTP_gain_vq_2_gain = new byte[32] { 126, 124, 125, 124, 129, 121, 126, 23, 132, 127, 127, 127, 126, 127, 122, 133, 130, 134, 101, 118, 119, 145, 126, 86, 124, 120, 123, 119, 170, 173, 107, 109 }; internal static readonly byte[][] silk_LTP_vq_gain_ptrs_Q7 = new byte[3][] { silk_LTP_gain_vq_0_gain, silk_LTP_gain_vq_1_gain, silk_LTP_gain_vq_2_gain }; internal static readonly sbyte[] silk_LTP_vq_sizes = new sbyte[3] { 8, 16, 32 }; internal static readonly byte[] silk_NLSF_CB1_NB_MB_Q8 = new byte[320] { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228, 15, 32, 55, 77, 101, 125, 151, 175, 201, 225, 19, 42, 66, 89, 114, 137, 162, 184, 209, 230, 12, 25, 50, 72, 97, 120, 147, 172, 200, 223, 26, 44, 69, 90, 114, 135, 159, 180, 205, 225, 13, 22, 53, 80, 106, 130, 156, 180, 205, 228, 15, 25, 44, 64, 90, 115, 142, 168, 196, 222, 19, 24, 62, 82, 100, 120, 145, 168, 190, 214, 22, 31, 50, 79, 103, 120, 151, 170, 203, 227, 21, 29, 45, 65, 106, 124, 150, 171, 196, 224, 30, 49, 75, 97, 121, 142, 165, 186, 209, 229, 19, 25, 52, 70, 93, 116, 143, 166, 192, 219, 26, 34, 62, 75, 97, 118, 145, 167, 194, 217, 25, 33, 56, 70, 91, 113, 143, 165, 196, 223, 21, 34, 51, 72, 97, 117, 145, 171, 196, 222, 20, 29, 50, 67, 90, 117, 144, 168, 197, 221, 22, 31, 48, 66, 95, 117, 146, 168, 196, 222, 24, 33, 51, 77, 116, 134, 158, 180, 200, 224, 21, 28, 70, 87, 106, 124, 149, 170, 194, 217, 26, 33, 53, 64, 83, 117, 152, 173, 204, 225, 27, 34, 65, 95, 108, 129, 155, 174, 210, 225, 20, 26, 72, 99, 113, 131, 154, 176, 200, 219, 34, 43, 61, 78, 93, 114, 155, 177, 205, 229, 23, 29, 54, 97, 124, 138, 163, 179, 209, 229, 30, 38, 56, 89, 118, 129, 158, 178, 200, 231, 21, 29, 49, 63, 85, 111, 142, 163, 193, 222, 27, 48, 77, 103, 133, 158, 179, 196, 215, 232, 29, 47, 74, 99, 124, 151, 176, 198, 220, 237, 33, 42, 61, 76, 93, 121, 155, 174, 207, 225, 29, 53, 87, 112, 136, 154, 170, 188, 208, 227, 24, 30, 52, 84, 131, 150, 166, 186, 203, 229, 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 }; internal static readonly byte[] silk_NLSF_CB1_iCDF_NB_MB = new byte[64] { 212, 178, 148, 129, 108, 96, 85, 82, 79, 77, 61, 59, 57, 56, 51, 49, 48, 45, 42, 41, 40, 38, 36, 34, 31, 30, 21, 12, 10, 3, 1, 0, 255, 245, 244, 236, 233, 225, 217, 203, 190, 176, 175, 161, 149, 136, 125, 114, 102, 91, 81, 71, 60, 52, 43, 35, 28, 20, 19, 18, 12, 11, 5, 0 }; internal static readonly byte[] silk_NLSF_CB2_SELECT_NB_MB = new byte[160] { 16, 0, 0, 0, 0, 99, 66, 36, 36, 34, 36, 34, 34, 34, 34, 83, 69, 36, 52, 34, 116, 102, 70, 68, 68, 176, 102, 68, 68, 34, 65, 85, 68, 84, 36, 116, 141, 152, 139, 170, 132, 187, 184, 216, 137, 132, 249, 168, 185, 139, 104, 102, 100, 68, 68, 178, 218, 185, 185, 170, 244, 216, 187, 187, 170, 244, 187, 187, 219, 138, 103, 155, 184, 185, 137, 116, 183, 155, 152, 136, 132, 217, 184, 184, 170, 164, 217, 171, 155, 139, 244, 169, 184, 185, 170, 164, 216, 223, 218, 138, 214, 143, 188, 218, 168, 244, 141, 136, 155, 170, 168, 138, 220, 219, 139, 164, 219, 202, 216, 137, 168, 186, 246, 185, 139, 116, 185, 219, 185, 138, 100, 100, 134, 100, 102, 34, 68, 68, 100, 68, 168, 203, 221, 218, 168, 167, 154, 136, 104, 70, 164, 246, 171, 137, 139, 137, 155, 218, 219, 139 }; internal static readonly byte[] silk_NLSF_CB2_iCDF_NB_MB = new byte[72] { 255, 254, 253, 238, 14, 3, 2, 1, 0, 255, 254, 252, 218, 35, 3, 2, 1, 0, 255, 254, 250, 208, 59, 4, 2, 1, 0, 255, 254, 246, 194, 71, 10, 2, 1, 0, 255, 252, 236, 183, 82, 8, 2, 1, 0, 255, 252, 235, 180, 90, 17, 2, 1, 0, 255, 248, 224, 171, 97, 30, 4, 1, 0, 255, 254, 236, 173, 95, 37, 7, 1, 0 }; internal static readonly byte[] silk_NLSF_CB2_BITS_NB_MB_Q5 = new byte[72] { 255, 255, 255, 131, 6, 145, 255, 255, 255, 255, 255, 236, 93, 15, 96, 255, 255, 255, 255, 255, 194, 83, 25, 71, 221, 255, 255, 255, 255, 162, 73, 34, 66, 162, 255, 255, 255, 210, 126, 73, 43, 57, 173, 255, 255, 255, 201, 125, 71, 48, 58, 130, 255, 255, 255, 166, 110, 73, 57, 62, 104, 210, 255, 255, 251, 123, 65, 55, 68, 100, 171, 255 }; internal static readonly byte[] silk_NLSF_PRED_NB_MB_Q8 = new byte[18] { 179, 138, 140, 148, 151, 149, 153, 151, 163, 116, 67, 82, 59, 92, 72, 100, 89, 92 }; internal static readonly short[] silk_NLSF_DELTA_MIN_NB_MB_Q15 = new short[11] { 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461 }; internal static readonly NLSFCodebook silk_NLSF_CB_NB_MB = new NLSFCodebook { nVectors = 32, order = 10, quantStepSize_Q16 = 11796, invQuantStepSize_Q6 = 356, CB1_NLSF_Q8 = silk_NLSF_CB1_NB_MB_Q8, CB1_iCDF = silk_NLSF_CB1_iCDF_NB_MB, pred_Q8 = silk_NLSF_PRED_NB_MB_Q8, ec_sel = silk_NLSF_CB2_SELECT_NB_MB, ec_iCDF = silk_NLSF_CB2_iCDF_NB_MB, ec_Rates_Q5 = silk_NLSF_CB2_BITS_NB_MB_Q5, deltaMin_Q15 = silk_NLSF_DELTA_MIN_NB_MB_Q15 }; internal static readonly byte[] silk_NLSF_CB1_WB_Q8 = new byte[512] { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239, 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236, 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240, 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237, 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240, 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236, 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218, 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236, 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237, 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241, 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225, 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234, 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233, 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237, 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240, 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237, 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236, 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237, 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238, 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239, 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235, 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238, 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236, 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237, 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240, 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239, 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241, 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231, 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242, 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239, 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240, 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 }; internal static readonly byte[] silk_NLSF_CB1_iCDF_WB = new byte[64] { 225, 204, 201, 184, 183, 175, 158, 154, 153, 135, 119, 115, 113, 110, 109, 99, 98, 95, 79, 68, 52, 50, 48, 45, 43, 32, 31, 27, 18, 10, 3, 0, 255, 251, 235, 230, 212, 201, 196, 182, 167, 166, 163, 151, 138, 124, 110, 104, 90, 78, 76, 70, 69, 57, 45, 34, 24, 21, 11, 6, 5, 4, 3, 0 }; internal static readonly byte[] silk_NLSF_CB2_SELECT_WB = new byte[256] { 0, 0, 0, 0, 0, 0, 0, 1, 100, 102, 102, 68, 68, 36, 34, 96, 164, 107, 158, 185, 180, 185, 139, 102, 64, 66, 36, 34, 34, 0, 1, 32, 208, 139, 141, 191, 152, 185, 155, 104, 96, 171, 104, 166, 102, 102, 102, 132, 1, 0, 0, 0, 0, 16, 16, 0, 80, 109, 78, 107, 185, 139, 103, 101, 208, 212, 141, 139, 173, 153, 123, 103, 36, 0, 0, 0, 0, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 32, 68, 135, 123, 119, 119, 103, 69, 98, 68, 103, 120, 118, 118, 102, 71, 98, 134, 136, 157, 184, 182, 153, 139, 134, 208, 168, 248, 75, 189, 143, 121, 107, 32, 49, 34, 34, 34, 0, 17, 2, 210, 235, 139, 123, 185, 137, 105, 134, 98, 135, 104, 182, 100, 183, 171, 134, 100, 70, 68, 70, 66, 66, 34, 131, 64, 166, 102, 68, 36, 2, 1, 0, 134, 166, 102, 68, 34, 34, 66, 132, 212, 246, 158, 139, 107, 107, 87, 102, 100, 219, 125, 122, 137, 118, 103, 132, 114, 135, 137, 105, 171, 106, 50, 34, 164, 214, 141, 143, 185, 151, 121, 103, 192, 34, 0, 0, 0, 0, 0, 1, 208, 109, 74, 187, 134, 249, 159, 137, 102, 110, 154, 118, 87, 101, 119, 101, 0, 2, 0, 36, 36, 66, 68, 35, 96, 164, 102, 100, 36, 0, 2, 33, 167, 138, 174, 102, 100, 84, 2, 2, 100, 107, 120, 119, 36, 197, 24, 0 }; internal static readonly byte[] silk_NLSF_CB2_iCDF_WB = new byte[72] { 255, 254, 253, 244, 12, 3, 2, 1, 0, 255, 254, 252, 224, 38, 3, 2, 1, 0, 255, 254, 251, 209, 57, 4, 2, 1, 0, 255, 254, 244, 195, 69, 4, 2, 1, 0, 255, 251, 232, 184, 84, 7, 2, 1, 0, 255, 254, 240, 186, 86, 14, 2, 1, 0, 255, 254, 239, 178, 91, 30, 5, 1, 0, 255, 248, 227, 177, 100, 19, 2, 1, 0 }; internal static readonly byte[] silk_NLSF_CB2_BITS_WB_Q5 = new byte[72] { 255, 255, 255, 156, 4, 154, 255, 255, 255, 255, 255, 227, 102, 15, 92, 255, 255, 255, 255, 255, 213, 83, 24, 72, 236, 255, 255, 255, 255, 150, 76, 33, 63, 214, 255, 255, 255, 190, 121, 77, 43, 55, 185, 255, 255, 255, 245, 137, 71, 43, 59, 139, 255, 255, 255, 255, 131, 66, 50, 66, 107, 194, 255, 255, 166, 116, 76, 55, 53, 125, 255, 255 }; internal static readonly byte[] silk_NLSF_PRED_WB_Q8 = new byte[30] { 175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182, 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155 }; internal static readonly short[] silk_NLSF_DELTA_MIN_WB_Q15 = new short[17] { 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347 }; internal static readonly NLSFCodebook silk_NLSF_CB_WB = new NLSFCodebook { nVectors = 32, order = 16, quantStepSize_Q16 = 9830, invQuantStepSize_Q6 = 427, CB1_NLSF_Q8 = silk_NLSF_CB1_WB_Q8, CB1_iCDF = silk_NLSF_CB1_iCDF_WB, pred_Q8 = silk_NLSF_PRED_WB_Q8, ec_sel = silk_NLSF_CB2_SELECT_WB, ec_iCDF = silk_NLSF_CB2_iCDF_WB, ec_Rates_Q5 = silk_NLSF_CB2_BITS_WB_Q5, deltaMin_Q15 = silk_NLSF_DELTA_MIN_WB_Q15 }; internal static readonly int[] silk_TargetRate_table_NB = new int[8] { 0, 8000, 9400, 11500, 13500, 17500, 25000, 80000 }; internal static readonly int[] silk_TargetRate_table_MB = new int[8] { 0, 9000, 12000, 14500, 18500, 24500, 35500, 80000 }; internal static readonly int[] silk_TargetRate_table_WB = new int[8] { 0, 10500, 14000, 17000, 21500, 28500, 42000, 80000 }; internal static readonly short[] silk_SNR_table_Q1 = new short[8] { 18, 29, 38, 40, 46, 52, 62, 84 }; internal static readonly short[] silk_stereo_pred_quant_Q13 = new short[16] { -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732 }; internal static readonly byte[] silk_stereo_pred_joint_iCDF = new byte[25] { 249, 247, 246, 245, 244, 234, 210, 202, 201, 200, 197, 174, 82, 59, 56, 55, 54, 46, 22, 12, 11, 10, 9, 7, 0 }; internal static readonly byte[] silk_stereo_only_code_mid_iCDF = new byte[2] { 64, 0 }; internal static readonly byte[] silk_LBRR_flags_2_iCDF = new byte[3] { 203, 150, 0 }; internal static readonly byte[] silk_LBRR_flags_3_iCDF = new byte[7] { 215, 195, 166, 125, 110, 82, 0 }; internal static readonly byte[][] silk_LBRR_flags_iCDF_ptr = new byte[2][] { silk_LBRR_flags_2_iCDF, silk_LBRR_flags_3_iCDF }; internal static readonly byte[] silk_lsb_iCDF = new byte[2] { 120, 0 }; internal static readonly byte[] silk_LTPscale_iCDF = new byte[3] { 128, 64, 0 }; internal static readonly byte[] silk_type_offset_VAD_iCDF = new byte[4] { 232, 158, 10, 0 }; internal static readonly byte[] silk_type_offset_no_VAD_iCDF = new byte[2] { 230, 0 }; internal static readonly byte[] silk_NLSF_interpolation_factor_iCDF = new byte[5] { 243, 221, 192, 181, 0 }; internal static readonly short[][] silk_Quantization_Offsets_Q10 = new short[2][] { new short[2] { 100, 240 }, new short[2] { 32, 100 } }; internal static readonly short[] silk_LTPScales_table_Q14 = new short[3] { 15565, 12288, 8192 }; internal static readonly byte[] silk_uniform3_iCDF = new byte[3] { 171, 85, 0 }; internal static readonly byte[] silk_uniform4_iCDF = new byte[4] { 192, 128, 64, 0 }; internal static readonly byte[] silk_uniform5_iCDF = new byte[5] { 205, 154, 102, 51, 0 }; internal static readonly byte[] silk_uniform6_iCDF = new byte[6] { 213, 171, 128, 85, 43, 0 }; internal static readonly byte[] silk_uniform8_iCDF = new byte[8] { 224, 192, 160, 128, 96, 64, 32, 0 }; internal static readonly byte[] silk_NLSF_EXT_iCDF = new byte[7] { 100, 40, 16, 7, 3, 1, 0 }; internal static readonly int[][] silk_Transition_LP_B_Q28 = new int[5][] { new int[3] { 250767114, 501534038, 250767114 }, new int[3] { 209867381, 419732057, 209867381 }, new int[3] { 170987846, 341967853, 170987846 }, new int[3] { 131531482, 263046905, 131531482 }, new int[3] { 89306658, 178584282, 89306658 } }; internal static readonly int[][] silk_Transition_LP_A_Q28 = new int[5][] { new int[2] { 506393414, 239854379 }, new int[2] { 411067935, 169683996 }, new int[2] { 306733530, 116694253 }, new int[2] { 185807084, 77959395 }, new int[2] { 35497197, 57401098 } }; internal static readonly byte[] silk_pitch_lag_iCDF = new byte[32] { 253, 250, 244, 233, 212, 182, 150, 131, 120, 110, 98, 85, 72, 60, 49, 40, 32, 25, 19, 15, 13, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; internal static readonly byte[] silk_pitch_delta_iCDF = new byte[21] { 210, 208, 206, 203, 199, 193, 183, 168, 142, 104, 74, 52, 37, 27, 20, 14, 10, 6, 4, 2, 0 }; internal static readonly byte[] silk_pitch_contour_iCDF = new byte[34] { 223, 201, 183, 167, 152, 138, 124, 111, 98, 88, 79, 70, 62, 56, 50, 44, 39, 35, 31, 27, 24, 21, 18, 16, 14, 12, 10, 8, 6, 4, 3, 2, 1, 0 }; internal static readonly byte[] silk_pitch_contour_NB_iCDF = new byte[11] { 188, 176, 155, 138, 119, 97, 67, 43, 26, 10, 0 }; internal static readonly byte[] silk_pitch_contour_10_ms_iCDF = new byte[12] { 165, 119, 80, 61, 47, 35, 27, 20, 14, 9, 4, 0 }; internal static readonly byte[] silk_pitch_contour_10_ms_NB_iCDF = new byte[3] { 113, 63, 0 }; internal static readonly byte[] silk_max_pulses_table = new byte[4] { 8, 10, 12, 16 }; internal static readonly byte[][] silk_pulses_per_block_iCDF = new byte[10][] { new byte[18] { 125, 51, 26, 18, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, new byte[18] { 198, 105, 45, 22, 15, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, new byte[18] { 213, 162, 116, 83, 59, 43, 32, 24, 18, 15, 12, 9, 7, 6, 5, 3, 2, 0 }, new byte[18] { 239, 187, 116, 59, 28, 16, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, new byte[18] { 250, 229, 188, 135, 86, 51, 30, 19, 13, 10, 8, 6, 5, 4, 3, 2, 1, 0 }, new byte[18] { 249, 235, 213, 185, 156, 128, 103, 83, 66, 53, 42, 33, 26, 21, 17, 13, 10, 0 }, new byte[18] { 254, 249, 235, 206, 164, 118, 77, 46, 27, 16, 10, 7, 5, 4, 3, 2, 1, 0 }, new byte[18] { 255, 253, 249, 239, 220, 191, 156, 119, 85, 57, 37, 23, 15, 10, 6, 4, 2, 0 }, new byte[18] { 255, 253, 251, 246, 237, 223, 203, 179, 152, 124, 98, 75, 55, 40, 29, 21, 15, 0 }, new byte[18] { 255, 254, 253, 247, 220, 162, 106, 67, 42, 28, 18, 12, 9, 6, 4, 3, 2, 0 } }; internal static readonly byte[][] silk_pulses_per_block_BITS_Q5 = new byte[9][] { new byte[18] { 31, 57, 107, 160, 205, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, new byte[18] { 69, 47, 67, 111, 166, 205, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, new byte[18] { 82, 74, 79, 95, 109, 128, 145, 160, 173, 205, 205, 205, 224, 255, 255, 224, 255, 224 }, new byte[18] { 125, 74, 59, 69, 97, 141, 182, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, new byte[18] { 173, 115, 85, 73, 76, 92, 115, 145, 173, 205, 224, 224, 255, 255, 255, 255, 255, 255 }, new byte[18] { 166, 134, 113, 102, 101, 102, 107, 118, 125, 138, 145, 155, 166, 182, 192, 192, 205, 150 }, new byte[18] { 224, 182, 134, 101, 83, 79, 85, 97, 120, 145, 173, 205, 224, 255, 255, 255, 255, 255 }, new byte[18] { 255, 224, 192, 150, 120, 101, 92, 89, 93, 102, 118, 134, 160, 182, 192, 224, 224, 224 }, new byte[18] { 255, 224, 224, 182, 155, 134, 118, 109, 104, 102, 106, 111, 118, 131, 145, 160, 173, 131 } }; internal static readonly byte[][] silk_rate_levels_iCDF = new byte[2][] { new byte[9] { 241, 190, 178, 132, 87, 74, 41, 14, 0 }, new byte[9] { 223, 193, 157, 140, 106, 57, 39, 18, 0 } }; internal static readonly byte[][] silk_rate_levels_BITS_Q5 = new byte[2][] { new byte[9] { 131, 74, 141, 79, 80, 138, 95, 104, 134 }, new byte[9] { 95, 99, 91, 125, 93, 76, 123, 115, 123 } }; internal static readonly byte[] silk_shell_code_table0 = new byte[152] { 128, 0, 214, 42, 0, 235, 128, 21, 0, 244, 184, 72, 11, 0, 248, 214, 128, 42, 7, 0, 248, 225, 170, 80, 25, 5, 0, 251, 236, 198, 126, 54, 18, 3, 0, 250, 238, 211, 159, 82, 35, 15, 5, 0, 250, 231, 203, 168, 128, 88, 53, 25, 6, 0, 252, 238, 216, 185, 148, 108, 71, 40, 18, 4, 0, 253, 243, 225, 199, 166, 128, 90, 57, 31, 13, 3, 0, 254, 246, 233, 212, 183, 147, 109, 73, 44, 23, 10, 2, 0, 255, 250, 240, 223, 198, 166, 128, 90, 58, 33, 16, 6, 1, 0, 255, 251, 244, 231, 210, 181, 146, 110, 75, 46, 25, 12, 5, 1, 0, 255, 253, 248, 238, 221, 196, 164, 128, 92, 60, 35, 18, 8, 3, 1, 0, 255, 253, 249, 242, 229, 208, 180, 146, 110, 76, 48, 27, 14, 7, 3, 1, 0 }; internal static readonly byte[] silk_shell_code_table1 = new byte[152] { 129, 0, 207, 50, 0, 236, 129, 20, 0, 245, 185, 72, 10, 0, 249, 213, 129, 42, 6, 0, 250, 226, 169, 87, 27, 4, 0, 251, 233, 194, 130, 62, 20, 4, 0, 250, 236, 207, 160, 99, 47, 17, 3, 0, 255, 240, 217, 182, 131, 81, 41, 11, 1, 0, 255, 254, 233, 201, 159, 107, 61, 20, 2, 1, 0, 255, 249, 233, 206, 170, 128, 86, 50, 23, 7, 1, 0, 255, 250, 238, 217, 186, 148, 108, 70, 39, 18, 6, 1, 0, 255, 252, 243, 226, 200, 166, 128, 90, 56, 30, 13, 4, 1, 0, 255, 252, 245, 231, 209, 180, 146, 110, 76, 47, 25, 11, 4, 1, 0, 255, 253, 248, 237, 219, 194, 163, 128, 93, 62, 37, 19, 8, 3, 1, 0, 255, 254, 250, 241, 226, 205, 177, 145, 111, 79, 51, 30, 15, 6, 2, 1, 0 }; internal static readonly byte[] silk_shell_code_table2 = new byte[152] { 129, 0, 203, 54, 0, 234, 129, 23, 0, 245, 184, 73, 10, 0, 250, 215, 129, 41, 5, 0, 252, 232, 173, 86, 24, 3, 0, 253, 240, 200, 129, 56, 15, 2, 0, 253, 244, 217, 164, 94, 38, 10, 1, 0, 253, 245, 226, 189, 132, 71, 27, 7, 1, 0, 253, 246, 231, 203, 159, 105, 56, 23, 6, 1, 0, 255, 248, 235, 213, 179, 133, 85, 47, 19, 5, 1, 0, 255, 254, 243, 221, 194, 159, 117, 70, 37, 12, 2, 1, 0, 255, 254, 248, 234, 208, 171, 128, 85, 48, 22, 8, 2, 1, 0, 255, 254, 250, 240, 220, 189, 149, 107, 67, 36, 16, 6, 2, 1, 0, 255, 254, 251, 243, 227, 201, 166, 128, 90, 55, 29, 13, 5, 2, 1, 0, 255, 254, 252, 246, 234, 213, 183, 147, 109, 73, 43, 22, 10, 4, 2, 1, 0 }; internal static readonly byte[] silk_shell_code_table3 = new byte[152] { 130, 0, 200, 58, 0, 231, 130, 26, 0, 244, 184, 76, 12, 0, 249, 214, 130, 43, 6, 0, 252, 232, 173, 87, 24, 3, 0, 253, 241, 203, 131, 56, 14, 2, 0, 254, 246, 221, 167, 94, 35, 8, 1, 0, 254, 249, 232, 193, 130, 65, 23, 5, 1, 0, 255, 251, 239, 211, 162, 99, 45, 15, 4, 1, 0, 255, 251, 243, 223, 186, 131, 74, 33, 11, 3, 1, 0, 255, 252, 245, 230, 202, 158, 105, 57, 24, 8, 2, 1, 0, 255, 253, 247, 235, 214, 179, 132, 84, 44, 19, 7, 2, 1, 0, 255, 254, 250, 240, 223, 196, 159, 112, 69, 36, 15, 6, 2, 1, 0, 255, 254, 253, 245, 231, 209, 176, 136, 93, 55, 27, 11, 3, 2, 1, 0, 255, 254, 253, 252, 239, 221, 194, 158, 117, 76, 42, 18, 4, 3, 2, 1, 0 }; internal static readonly byte[] silk_shell_code_table_offsets = new byte[17] { 0, 0, 2, 5, 9, 14, 20, 27, 35, 44, 54, 65, 77, 90, 104, 119, 135 }; internal static readonly byte[] silk_sign_iCDF = new byte[42] { 254, 49, 67, 77, 82, 93, 99, 198, 11, 18, 24, 31, 36, 45, 255, 46, 66, 78, 87, 94, 104, 208, 14, 21, 32, 42, 51, 66, 255, 94, 104, 109, 112, 115, 118, 248, 53, 69, 80, 88, 95, 102 }; internal static readonly sbyte[,] delay_matrix_enc = new sbyte[5, 3] { { 6, 0, 3 }, { 0, 7, 3 }, { 0, 1, 10 }, { 0, 2, 6 }, { 18, 10, 12 } }; internal static readonly sbyte[,] delay_matrix_dec = new sbyte[3, 5] { { 4, 0, 2, 0, 0 }, { 0, 9, 4, 7, 4 }, { 0, 3, 12, 7, 7 } }; internal static readonly short[] silk_Resampler_3_4_COEFS = new short[29] { -20694, -13867, -49, 64, 17, -157, 353, -496, 163, 11047, 22205, -39, 6, 91, -170, 186, 23, -896, 6336, 19928, -19, -36, 102, -89, -24, 328, -951, 2568, 15909 }; internal static readonly short[] silk_Resampler_2_3_COEFS = new short[20] { -14457, -14019, 64, 128, -122, 36, 310, -768, 584, 9267, 17733, 12, 128, 18, -142, 288, -117, -865, 4123, 14459 }; internal static readonly short[] silk_Resampler_1_2_COEFS = new short[14] { 616, -14323, -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024 }; internal static readonly short[] silk_Resampler_1_3_COEFS = new short[20] { 16102, -15162, -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271 }; internal static readonly short[] silk_Resampler_1_4_COEFS = new short[20] { 22500, -15099, 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464 }; internal static readonly short[] silk_Resampler_1_6_COEFS = new short[20] { 27540, -15257, 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455 }; internal static readonly short[] silk_Resampler_2_3_COEFS_LQ = new short[6] { -2797, -6507, 4697, 10739, 1567, 8276 }; internal static readonly short[,] silk_resampler_frac_FIR_12 = new short[12, 4] { { 189, -600, 617, 30567 }, { 117, -159, -1070, 29704 }, { 52, 221, -2392, 28276 }, { -4, 529, -3350, 26341 }, { -48, 758, -3956, 23973 }, { -80, 905, -4235, 21254 }, { -99, 972, -4222, 18278 }, { -107, 967, -3957, 15143 }, { -103, 896, -3487, 11950 }, { -91, 773, -2865, 8798 }, { -71, 611, -2143, 5784 }, { -46, 425, -1375, 2996 } }; internal const short silk_resampler_down2_0 = 9872; internal const short silk_resampler_down2_1 = -25727; internal static readonly short[] silk_resampler_up2_hq_0 = new short[3] { 1746, 14986, -26453 }; internal static readonly short[] silk_resampler_up2_hq_1 = new short[3] { 6854, 25769, -9994 }; internal static readonly sbyte[][] silk_CB_lags_stage2_10_ms = new sbyte[2][] { new sbyte[3] { 0, 1, 0 }, new sbyte[3] { 0, 0, 1 } }; internal static readonly sbyte[][] silk_CB_lags_stage3_10_ms = new sbyte[2][] { new sbyte[12] { 0, 0, 1, -1, 1, -1, 2, -2, 2, -2, 3, -3 }, new sbyte[12] { 0, 1, 0, 1, -1, 2, -1, 2, -2, 3, -2, 3 } }; internal static readonly sbyte[][] silk_CB_lags_stage2 = new sbyte[4][] { new sbyte[11] { 0, 2, -1, -1, -1, 0, 0, 1, 1, 0, 1 }, new sbyte[11] { 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, new sbyte[11] { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, new sbyte[11] { 0, -1, 2, 1, 0, 1, 1, 0, 0, -1, -1 } }; internal static readonly sbyte[][] silk_CB_lags_stage3 = new sbyte[4][] { new sbyte[34] { 0, 0, 1, -1, 0, 1, -1, 0, -1, 1, -2, 2, -2, -2, 2, -3, 2, 3, -3, -4, 3, -4, 4, 4, -5, 5, -6, -5, 6, -7, 6, 5, 8, -9 }, new sbyte[34] { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 1, -1, 0, 1, -1, -1, 1, -1, 2, 1, -1, 2, -2, -2, 2, -2, 2, 2, 3, -3 }, new sbyte[34] { 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, -1, 1, 0, 0, 2, 1, -1, 2, -1, -1, 2, -1, 2, 2, -1, 3, -2, -2, -2, 3 }, new sbyte[34] { 0, 1, 0, 0, 1, 0, 1, -1, 2, -1, 2, -1, 2, 3, -2, 3, -2, -2, 4, 4, -3, 5, -3, -4, 6, -4, 6, 5, -5, 8, -6, -5, -7, 9 } }; internal static readonly sbyte[][] silk_Lag_range_stage3_10_ms = new sbyte[2][] { new sbyte[2] { -3, 7 }, new sbyte[2] { -2, 7 } }; internal static readonly sbyte[][][] silk_Lag_range_stage3 = new sbyte[3][][] { new sbyte[4][] { new sbyte[2] { -5, 8 }, new sbyte[2] { -1, 6 }, new sbyte[2] { -1, 6 }, new sbyte[2] { -4, 10 } }, new sbyte[4][] { new sbyte[2] { -6, 10 }, new sbyte[2] { -2, 6 }, new sbyte[2] { -1, 6 }, new sbyte[2] { -5, 10 } }, new sbyte[4][] { new sbyte[2] { -9, 12 }, new sbyte[2] { -3, 7 }, new sbyte[2] { -2, 7 }, new sbyte[2] { -7, 13 } } }; internal static readonly sbyte[] silk_nb_cbk_searchs_stage3 = new sbyte[3] { 16, 24, 34 }; } internal class TuningParameters { internal const int BITRESERVOIR_DECAY_TIME_MS = 500; internal const float FIND_PITCH_WHITE_NOISE_FRACTION = 0.001f; internal const float FIND_PITCH_BANDWIDTH_EXPANSION = 0.99f; internal const float FIND_LPC_COND_FAC = 1E-05f; internal const float FIND_LTP_COND_FAC = 1E-05f; internal const float LTP_DAMPING = 0.05f; internal const float LTP_SMOOTHING = 0.1f; internal const float MU_LTP_QUANT_NB = 0.03f; internal const float MU_LTP_QUANT_MB = 0.025f; internal const float MU_LTP_QUANT_WB = 0.02f; internal const float MAX_SUM_LOG_GAIN_DB = 250f; internal const float VARIABLE_HP_SMTH_COEF1 = 0.1f; internal const float VARIABLE_HP_SMTH_COEF2 = 0.015f; internal const float VARIABLE_HP_MAX_DELTA_FREQ = 0.4f; internal const int VARIABLE_HP_MIN_CUTOFF_HZ = 60; internal const int VARIABLE_HP_MAX_CUTOFF_HZ = 100; internal const float SPEECH_ACTIVITY_DTX_THRES = 0.05f; internal const float LBRR_SPEECH_ACTIVITY_THRES = 0.3f; internal const float BG_SNR_DECR_dB = 2f; internal const float HARM_SNR_INCR_dB = 2f; internal const float SPARSE_SNR_INCR_dB = 2f; internal const float SPARSENESS_THRESHOLD_QNT_OFFSET = 0.75f; internal const float WARPING_MULTIPLIER = 0.015f; internal const float SHAPE_WHITE_NOISE_FRACTION = 5E-05f; internal const float BANDWIDTH_EXPANSION = 0.95f; internal const float LOW_RATE_BANDWIDTH_EXPANSION_DELTA = 0.01f; internal const float LOW_RATE_HARMONIC_BOOST = 0.1f; internal const float LOW_INPUT_QUALITY_HARMONIC_BOOST = 0.1f; internal const float HARMONIC_SHAPING = 0.3f; internal const float HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING = 0.2f; internal const float HP_NOISE_COEF = 0.25f; internal const float HARM_HP_NOISE_COEF = 0.35f; internal const float INPUT_TILT = 0.05f; internal const float HIGH_RATE_INPUT_TILT = 0.1f; internal const float LOW_FREQ_SHAPING = 4f; internal const float LOW_QUALITY_LOW_FREQ_SHAPING_DECR = 0.5f; internal const float SUBFR_SMTH_COEF = 0.4f; internal const float LAMBDA_OFFSET = 1.2f; internal const float LAMBDA_SPEECH_ACT = -0.2f; internal const float LAMBDA_DELAYED_DECISIONS = -0.05f; internal const float LAMBDA_INPUT_QUALITY = -0.1f; internal const float LAMBDA_CODING_QUALITY = -0.2f; internal const float LAMBDA_QUANT_OFFSET = 0.8f; internal const int REDUCE_BITRATE_10_MS_BPS = 2200; internal const int MAX_BANDWIDTH_SWITCH_DELAY_MS = 5000; } internal static class VoiceActivityDetection { private static readonly int[] tiltWeights = new int[4] { 30000, 6000, -12000, -12000 }; internal static int silk_VAD_Init(SilkVADState psSilk_VAD) { int result = 0; psSilk_VAD.Reset(); for (int i = 0; i < 4; i++) { psSilk_VAD.NoiseLevelBias[i] = Inlines.silk_max_32(Inlines.silk_DIV32_16(50, (short)(i + 1)), 1); } for (int i = 0; i < 4; i++) { psSilk_VAD.NL[i] = Inlines.silk_MUL(100, psSilk_VAD.NoiseLevelBias[i]); psSilk_VAD.inv_NL[i] = Inlines.silk_DIV32(int.MaxValue, psSilk_VAD.NL[i]); } psSilk_VAD.counter = 15; for (int i = 0; i < 4; i++) { psSilk_VAD.NrgRatioSmth_Q8[i] = 25600; } return result; } internal static int silk_VAD_GetSA_Q8(SilkChannelEncoder psEncC, Span pIn, int pIn_ptr) { int num = 0; int[] array = new int[4]; int[] array2 = new int[4]; int[] array3 = new int[4]; int result = 0; SilkVADState sVAD = psEncC.sVAD; int num2 = Inlines.silk_RSHIFT(psEncC.frame_length, 1); int num3 = Inlines.silk_RSHIFT(psEncC.frame_length, 2); int num4 = Inlines.silk_RSHIFT(psEncC.frame_length, 3); array3[0] = 0; array3[1] = num4 + num3; array3[2] = array3[1] + num4; array3[3] = array3[2] + num3; short[] array4 = new short[array3[3] + num2]; Filters.silk_ana_filt_bank_1(pIn, pIn_ptr, sVAD.AnaState, array4, array4, array3[3], psEncC.frame_length); Filters.silk_ana_filt_bank_1(array4, 0, sVAD.AnaState1, array4, array4, array3[2], num2); Filters.silk_ana_filt_bank_1(array4, 0, sVAD.AnaState2, array4, array4, array3[1], num3); array4[num4 - 1] = (short)Inlines.silk_RSHIFT(array4[num4 - 1], 1); short hPstate = array4[num4 - 1]; for (int num5 = num4 - 1; num5 > 0; num5--) { array4[num5 - 1] = (short)Inlines.silk_RSHIFT(array4[num5 - 1], 1); array4[num5] -= array4[num5 - 1]; } array4[0] -= sVAD.HPstate; sVAD.HPstate = hPstate; for (int i = 0; i < 4; i++) { num4 = Inlines.silk_RSHIFT(psEncC.frame_length, Inlines.silk_min_int(4 - i, 3)); int num6 = Inlines.silk_RSHIFT(num4, 2); int num7 = 0; array[i] = sVAD.XnrgSubfr[i]; for (int j = 0; j < 4; j++) { num = 0; for (int num5 = 0; num5 < num6; num5++) { int num8 = Inlines.silk_RSHIFT(array4[array3[i] + num5 + num7], 3); num = Inlines.silk_SMLABB(num, num8, num8); } if (j < 3) { array[i] = Inlines.silk_ADD_POS_SAT32(array[i], num); } else { array[i] = Inlines.silk_ADD_POS_SAT32(array[i], Inlines.silk_RSHIFT(num, 1)); } num7 += num6; } sVAD.XnrgSubfr[i] = num; } silk_VAD_GetNoiseLevels(array, sVAD); num = 0; int num9 = 0; int num10; for (int i = 0; i < 4; i++) { num10 = array[i] - sVAD.NL[i]; if (num10 > 0) { if ((array[i] & 0xFF800000u) == 0L) { array2[i] = Inlines.silk_DIV32(Inlines.silk_LSHIFT(array[i], 8), sVAD.NL[i] + 1); } else { array2[i] = Inlines.silk_DIV32(array[i], Inlines.silk_RSHIFT(sVAD.NL[i], 8) + 1); } int num11 = Inlines.silk_lin2log(array2[i]) - 1024; num = Inlines.silk_SMLABB(num, num11, num11); if (num10 < 1048576) { num11 = Inlines.silk_SMULWB(Inlines.silk_LSHIFT(Inlines.silk_SQRT_APPROX(num10), 6), num11); } num9 = Inlines.silk_SMLAWB(num9, tiltWeights[i], num11); } else { array2[i] = 256; } } num = Inlines.silk_DIV32_16(num, 4); int b = (short)(3 * Inlines.silk_SQRT_APPROX(num)); int num12 = Sigmoid.silk_sigm_Q15(Inlines.silk_SMULWB(45000, b) - 128); psEncC.input_tilt_Q15 = Inlines.silk_LSHIFT(Sigmoid.silk_sigm_Q15(num9) - 16384, 1); num10 = 0; for (int i = 0; i < 4; i++) { num10 += (i + 1) * Inlines.silk_RSHIFT(array[i] - sVAD.NL[i], 4); } if (num10 <= 0) { num12 = Inlines.silk_RSHIFT(num12, 1); } else if (num10 < 32768) { num10 = ((psEncC.frame_length != 10 * psEncC.fs_kHz) ? Inlines.silk_LSHIFT_SAT32(num10, 15) : Inlines.silk_LSHIFT_SAT32(num10, 16)); num10 = Inlines.silk_SQRT_APPROX(num10); num12 = Inlines.silk_SMULWB(32768 + num10, num12); } psEncC.speech_activity_Q8 = Inlines.silk_min_int(Inlines.silk_RSHIFT(num12, 7), 255); int num13 = Inlines.silk_SMULWB(4096, Inlines.silk_SMULWB(num12, num12)); if (psEncC.frame_length == 10 * psEncC.fs_kHz) { num13 >>= 1; } for (int i = 0; i < 4; i++) { sVAD.NrgRatioSmth_Q8[i] = Inlines.silk_SMLAWB(sVAD.NrgRatioSmth_Q8[i], array2[i] - sVAD.NrgRatioSmth_Q8[i], num13); int num11 = 3 * (Inlines.silk_lin2log(sVAD.NrgRatioSmth_Q8[i]) - 1024); psEncC.input_quality_bands_Q15[i] = Sigmoid.silk_sigm_Q15(Inlines.silk_RSHIFT(num11 - 2048, 4)); } return result; } internal static void silk_VAD_GetNoiseLevels(int[] pX, SilkVADState psSilk_VAD) { int b = ((psSilk_VAD.counter < 1000) ? Inlines.silk_DIV32_16(32767, (short)(Inlines.silk_RSHIFT(psSilk_VAD.counter, 4) + 1)) : 0); for (int i = 0; i < 4; i++) { int num = psSilk_VAD.NL[i]; int num2 = Inlines.silk_ADD_POS_SAT32(pX[i], psSilk_VAD.NoiseLevelBias[i]); int num3 = Inlines.silk_DIV32(int.MaxValue, num2); int a = ((num2 <= Inlines.silk_LSHIFT(num, 3)) ? ((num2 >= num) ? Inlines.silk_SMULWB(Inlines.silk_SMULWW(num3, num), 2048) : 1024) : 128); a = Inlines.silk_max_int(a, b); psSilk_VAD.inv_NL[i] = Inlines.silk_SMLAWB(psSilk_VAD.inv_NL[i], num3 - psSilk_VAD.inv_NL[i], a); num = Inlines.silk_DIV32(int.MaxValue, psSilk_VAD.inv_NL[i]); num = Inlines.silk_min(num, 16777215); psSilk_VAD.NL[i] = num; } psSilk_VAD.counter++; } } internal static class VQ_WMat_EC { internal static void silk_VQ_WMat_EC(BoxedValueSbyte ind, BoxedValueInt rate_dist_Q14, BoxedValueInt gain_Q7, short[] in_Q14, int in_Q14_ptr, int[] W_Q18, int W_Q18_ptr, sbyte[][] cb_Q7, byte[] cb_gain_Q7, byte[] cl_Q5, int mu_Q9, int max_gain_Q7, int L) { int num = 0; short[] array = new short[5]; rate_dist_Q14.Val = int.MaxValue; for (int i = 0; i < L; i++) { sbyte[] array2 = cb_Q7[num++]; int num2 = cb_gain_Q7[i]; array[0] = (short)(in_Q14[in_Q14_ptr] - Inlines.silk_LSHIFT(array2[0], 7)); array[1] = (short)(in_Q14[in_Q14_ptr + 1] - Inlines.silk_LSHIFT(array2[1], 7)); array[2] = (short)(in_Q14[in_Q14_ptr + 2] - Inlines.silk_LSHIFT(array2[2], 7)); array[3] = (short)(in_Q14[in_Q14_ptr + 3] - Inlines.silk_LSHIFT(array2[3], 7)); array[4] = (short)(in_Q14[in_Q14_ptr + 4] - Inlines.silk_LSHIFT(array2[4], 7)); int a = Inlines.silk_SMULBB(mu_Q9, cl_Q5[i]); a = Inlines.silk_ADD_LSHIFT32(a, Inlines.silk_max(Inlines.silk_SUB32(num2, max_gain_Q7), 0), 10); int a2 = Inlines.silk_SMULWB(W_Q18[W_Q18_ptr + 1], array[1]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 2], array[2]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 3], array[3]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 4], array[4]); a2 = Inlines.silk_LSHIFT(a2, 1); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr], array[0]); a = Inlines.silk_SMLAWB(a, a2, array[0]); a2 = Inlines.silk_SMULWB(W_Q18[W_Q18_ptr + 7], array[2]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 8], array[3]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 9], array[4]); a2 = Inlines.silk_LSHIFT(a2, 1); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 6], array[1]); a = Inlines.silk_SMLAWB(a, a2, array[1]); a2 = Inlines.silk_SMULWB(W_Q18[W_Q18_ptr + 13], array[3]); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 14], array[4]); a2 = Inlines.silk_LSHIFT(a2, 1); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 12], array[2]); a = Inlines.silk_SMLAWB(a, a2, array[2]); a2 = Inlines.silk_SMULWB(W_Q18[W_Q18_ptr + 19], array[4]); a2 = Inlines.silk_LSHIFT(a2, 1); a2 = Inlines.silk_SMLAWB(a2, W_Q18[W_Q18_ptr + 18], array[3]); a = Inlines.silk_SMLAWB(a, a2, array[3]); a2 = Inlines.silk_SMULWB(W_Q18[W_Q18_ptr + 24], array[4]); a = Inlines.silk_SMLAWB(a, a2, array[4]); if (a < rate_dist_Q14.Val) { rate_dist_Q14.Val = a; ind.Val = (sbyte)i; gain_Q7.Val = num2; } } } } } namespace Concentus.Silk.Structs { internal class CNGState { internal readonly int[] CNG_exc_buf_Q14 = new int[320]; internal readonly short[] CNG_smth_NLSF_Q15 = new short[16]; internal readonly int[] CNG_synth_state = new int[16]; internal int CNG_smth_Gain_Q16; internal int rand_seed; internal int fs_kHz; internal void Reset() { Arrays.MemSetInt(CNG_exc_buf_Q14, 0, 320); Arrays.MemSetShort(CNG_smth_NLSF_Q15, 0, 16); Arrays.MemSetInt(CNG_synth_state, 0, 16); CNG_smth_Gain_Q16 = 0; rand_seed = 0; fs_kHz = 0; } } internal class DecControlState { internal int nChannelsAPI; internal int nChannelsInternal; internal int API_sampleRate; internal int internalSampleRate; internal int payloadSize_ms; internal int prevPitchLag; internal void Reset() { nChannelsAPI = 0; nChannelsInternal = 0; API_sampleRate = 0; internalSampleRate = 0; payloadSize_ms = 0; prevPitchLag = 0; } } internal class EncControlState { internal int nChannelsAPI; internal int nChannelsInternal; internal int API_sampleRate; internal int maxInternalSampleRate; internal int minInternalSampleRate; internal int desiredInternalSampleRate; internal int payloadSize_ms; internal int bitRate; internal int packetLossPercentage; internal int complexity; internal int useInBandFEC; internal int useDTX; internal int useCBR; internal int maxBits; internal int toMono; internal int opusCanSwitch; internal int reducedDependency; internal int internalSampleRate; internal int allowBandwidthSwitch; internal int inWBmodeWithoutVariableLP; internal int stereoWidth_Q14; internal int switchReady; internal void Reset() { nChannelsAPI = 0; nChannelsInternal = 0; API_sampleRate = 0; maxInternalSampleRate = 0; minInternalSampleRate = 0; desiredInternalSampleRate = 0; payloadSize_ms = 0; bitRate = 0; packetLossPercentage = 0; complexity = 0; useInBandFEC = 0; useDTX = 0; useCBR = 0; maxBits = 0; toMono = 0; opusCanSwitch = 0; reducedDependency = 0; internalSampleRate = 0; allowBandwidthSwitch = 0; inWBmodeWithoutVariableLP = 0; stereoWidth_Q14 = 0; switchReady = 0; } internal int check_control_input() { if ((API_sampleRate != 8000 && API_sampleRate != 12000 && API_sampleRate != 16000 && API_sampleRate != 24000 && API_sampleRate != 32000 && API_sampleRate != 44100 && API_sampleRate != 48000) || (desiredInternalSampleRate != 8000 && desiredInternalSampleRate != 12000 && desiredInternalSampleRate != 16000) || (maxInternalSampleRate != 8000 && maxInternalSampleRate != 12000 && maxInternalSampleRate != 16000) || (minInternalSampleRate != 8000 && minInternalSampleRate != 12000 && minInternalSampleRate != 16000) || minInternalSampleRate > desiredInternalSampleRate || maxInternalSampleRate < desiredInternalSampleRate || minInternalSampleRate > maxInternalSampleRate) { return SilkError.SILK_ENC_FS_NOT_SUPPORTED; } if (payloadSize_ms != 10 && payloadSize_ms != 20 && payloadSize_ms != 40 && payloadSize_ms != 60) { return SilkError.SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; } if (packetLossPercentage < 0 || packetLossPercentage > 100) { return SilkError.SILK_ENC_INVALID_LOSS_RATE; } if (useDTX < 0 || useDTX > 1) { return SilkError.SILK_ENC_INVALID_DTX_SETTING; } if (useCBR < 0 || useCBR > 1) { return SilkError.SILK_ENC_INVALID_CBR_SETTING; } if (useInBandFEC < 0 || useInBandFEC > 1) { return SilkError.SILK_ENC_INVALID_INBAND_FEC_SETTING; } if (nChannelsAPI < 1 || nChannelsAPI > 2) { return SilkError.SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if (nChannelsInternal < 1 || nChannelsInternal > 2) { return SilkError.SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if (nChannelsInternal > nChannelsAPI) { return SilkError.SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; } if (complexity < 0 || complexity > 10) { return SilkError.SILK_ENC_INVALID_COMPLEXITY_SETTING; } return SilkError.SILK_NO_ERROR; } } internal class NLSFCodebook { internal short nVectors; internal short order; internal short quantStepSize_Q16; internal short invQuantStepSize_Q6; internal byte[] CB1_NLSF_Q8; internal byte[] CB1_iCDF; internal byte[] pred_Q8; internal byte[] ec_sel; internal byte[] ec_iCDF; internal byte[] ec_Rates_Q5; internal short[] deltaMin_Q15; internal void Reset() { nVectors = 0; order = 0; quantStepSize_Q16 = 0; invQuantStepSize_Q6 = 0; CB1_NLSF_Q8 = null; CB1_iCDF = null; pred_Q8 = null; ec_sel = null; ec_iCDF = null; ec_Rates_Q5 = null; deltaMin_Q15 = null; } } internal class PLCStruct { internal int pitchL_Q8; internal readonly short[] LTPCoef_Q14 = new short[5]; internal readonly short[] prevLPC_Q12 = new short[16]; internal int last_frame_lost; internal int rand_seed; internal short randScale_Q14; internal int conc_energy; internal int conc_energy_shift; internal short prevLTP_scale_Q14; internal readonly int[] prevGain_Q16 = new int[2]; internal int fs_kHz; internal int nb_subfr; internal int subfr_length; internal void Reset() { pitchL_Q8 = 0; Arrays.MemSetShort(LTPCoef_Q14, 0, 5); Arrays.MemSetShort(prevLPC_Q12, 0, 16); last_frame_lost = 0; rand_seed = 0; randScale_Q14 = 0; conc_energy = 0; conc_energy_shift = 0; prevLTP_scale_Q14 = 0; Arrays.MemSetInt(prevGain_Q16, 0, 2); fs_kHz = 0; nb_subfr = 0; subfr_length = 0; } } internal class SideInfoIndices { internal readonly sbyte[] GainsIndices = new sbyte[4]; internal readonly sbyte[] LTPIndex = new sbyte[4]; internal readonly sbyte[] NLSFIndices = new sbyte[17]; internal short lagIndex; internal sbyte contourIndex; internal sbyte signalType; internal sbyte quantOffsetType; internal sbyte NLSFInterpCoef_Q2; internal sbyte PERIndex; internal sbyte LTP_scaleIndex; internal sbyte Seed; internal void Reset() { Arrays.MemSetSbyte(GainsIndices, 0, 4); Arrays.MemSetSbyte(LTPIndex, 0, 4); Arrays.MemSetSbyte(NLSFIndices, 0, 17); lagIndex = 0; contourIndex = 0; signalType = 0; quantOffsetType = 0; NLSFInterpCoef_Q2 = 0; PERIndex = 0; LTP_scaleIndex = 0; Seed = 0; } internal void Assign(SideInfoIndices other) { Arrays.MemCopy(other.GainsIndices, 0, GainsIndices, 0, 4); Arrays.MemCopy(other.LTPIndex, 0, LTPIndex, 0, 4); Arrays.MemCopy(other.NLSFIndices, 0, NLSFIndices, 0, 17); lagIndex = other.lagIndex; contourIndex = other.contourIndex; signalType = other.signalType; quantOffsetType = other.quantOffsetType; NLSFInterpCoef_Q2 = other.NLSFInterpCoef_Q2; PERIndex = other.PERIndex; LTP_scaleIndex = other.LTP_scaleIndex; Seed = other.Seed; } } internal class SilkChannelDecoder { internal int prev_gain_Q16; internal readonly int[] exc_Q14 = new int[320]; internal readonly int[] sLPC_Q14_buf = new int[16]; internal readonly short[] outBuf = new short[480]; internal int lagPrev; internal sbyte LastGainIndex; internal int fs_kHz; internal int fs_API_hz; internal int nb_subfr; internal int frame_length; internal int subfr_length; internal int ltp_mem_length; internal int LPC_order; internal readonly short[] prevNLSF_Q15 = new short[16]; internal int first_frame_after_reset; internal byte[] pitch_lag_low_bits_iCDF; internal byte[] pitch_contour_iCDF; internal int nFramesDecoded; internal int nFramesPerPacket; internal int ec_prevSignalType; internal short ec_prevLagIndex; internal readonly int[] VAD_flags = new int[3]; internal int LBRR_flag; internal readonly int[] LBRR_flags = new int[3]; internal readonly SilkResamplerState resampler_state = new SilkResamplerState(); internal NLSFCodebook psNLSF_CB; internal readonly SideInfoIndices indices = new SideInfoIndices(); internal readonly CNGState sCNG = new CNGState(); internal int lossCnt; internal int prevSignalType; internal readonly PLCStruct sPLC = new PLCStruct(); internal void Reset() { prev_gain_Q16 = 0; Arrays.MemSetInt(exc_Q14, 0, 320); Arrays.MemSetInt(sLPC_Q14_buf, 0, 16); Arrays.MemSetShort(outBuf, 0, 480); lagPrev = 0; LastGainIndex = 0; fs_kHz = 0; fs_API_hz = 0; nb_subfr = 0; frame_length = 0; subfr_length = 0; ltp_mem_length = 0; LPC_order = 0; Arrays.MemSetShort(prevNLSF_Q15, 0, 16); first_frame_after_reset = 0; pitch_lag_low_bits_iCDF = null; pitch_contour_iCDF = null; nFramesDecoded = 0; nFramesPerPacket = 0; ec_prevSignalType = 0; ec_prevLagIndex = 0; Arrays.MemSetInt(VAD_flags, 0, 3); LBRR_flag = 0; Arrays.MemSetInt(LBRR_flags, 0, 3); resampler_state.Reset(); psNLSF_CB = null; indices.Reset(); sCNG.Reset(); lossCnt = 0; prevSignalType = 0; sPLC.Reset(); } internal int silk_init_decoder() { Reset(); first_frame_after_reset = 1; prev_gain_Q16 = 65536; silk_CNG_Reset(); silk_PLC_Reset(); return 0; } private void silk_CNG_Reset() { int num = Inlines.silk_DIV32_16(32767, LPC_order + 1); int num2 = 0; for (int i = 0; i < LPC_order; i++) { num2 += num; sCNG.CNG_smth_NLSF_Q15[i] = (short)num2; } sCNG.CNG_smth_Gain_Q16 = 0; sCNG.rand_seed = 3176576; } private void silk_PLC_Reset() { sPLC.pitchL_Q8 = Inlines.silk_LSHIFT(frame_length, 7); sPLC.prevGain_Q16[0] = 65536; sPLC.prevGain_Q16[1] = 65536; sPLC.subfr_length = 20; sPLC.nb_subfr = 2; } internal int silk_decoder_set_fs(int fs_kHz, int fs_API_Hz) { int num = 0; subfr_length = Inlines.silk_SMULBB(5, fs_kHz); int num2 = Inlines.silk_SMULBB(nb_subfr, subfr_length); if (this.fs_kHz != fs_kHz || fs_API_hz != fs_API_Hz) { num += Resampler.silk_resampler_init(resampler_state, Inlines.silk_SMULBB(fs_kHz, 1000), fs_API_Hz, 0); fs_API_hz = fs_API_Hz; } if (this.fs_kHz != fs_kHz || num2 != frame_length) { if (fs_kHz == 8) { if (nb_subfr == 4) { pitch_contour_iCDF = Tables.silk_pitch_contour_NB_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_NB_iCDF; } } else if (nb_subfr == 4) { pitch_contour_iCDF = Tables.silk_pitch_contour_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_iCDF; } if (this.fs_kHz != fs_kHz) { ltp_mem_length = Inlines.silk_SMULBB(20, fs_kHz); if (fs_kHz == 8 || fs_kHz == 12) { LPC_order = 10; psNLSF_CB = Tables.silk_NLSF_CB_NB_MB; } else { LPC_order = 16; psNLSF_CB = Tables.silk_NLSF_CB_WB; } switch (fs_kHz) { case 16: pitch_lag_low_bits_iCDF = Tables.silk_uniform8_iCDF; break; case 12: pitch_lag_low_bits_iCDF = Tables.silk_uniform6_iCDF; break; case 8: pitch_lag_low_bits_iCDF = Tables.silk_uniform4_iCDF; break; } first_frame_after_reset = 1; lagPrev = 100; LastGainIndex = 10; prevSignalType = 0; Arrays.MemSetShort(outBuf, 0, 480); Arrays.MemSetInt(sLPC_Q14_buf, 0, 16); } this.fs_kHz = fs_kHz; frame_length = num2; } return num; } internal int silk_decode_frame(EntropyCoder psRangeDec, ReadOnlySpan frameData, Span pOut, int pOut_ptr, BoxedValueInt pN, int lostFlag, int condCoding) { SilkDecoderControl silkDecoderControl = new SilkDecoderControl(); int num = frame_length; silkDecoderControl.LTP_scale_Q14 = 0; if (lostFlag == 0 || (lostFlag == 2 && LBRR_flags[nFramesDecoded] == 1)) { short[] pulses = new short[(num + 16 - 1) & -16]; DecodeIndices.silk_decode_indices(this, psRangeDec, frameData, nFramesDecoded, lostFlag, condCoding); DecodePulses.silk_decode_pulses(psRangeDec, frameData, pulses, indices.signalType, indices.quantOffsetType, frame_length); DecodeParameters.silk_decode_parameters(this, silkDecoderControl, condCoding); DecodeCore.silk_decode_core(this, silkDecoderControl, pOut, pOut_ptr, pulses); PLC.silk_PLC(this, silkDecoderControl, pOut, pOut_ptr, 0); lossCnt = 0; prevSignalType = indices.signalType; first_frame_after_reset = 0; } else { PLC.silk_PLC(this, silkDecoderControl, pOut, pOut_ptr, 1); } int num2 = ltp_mem_length - frame_length; Arrays.MemMoveShort(outBuf, frame_length, 0, num2); pOut.Slice(pOut_ptr, frame_length).CopyTo(MemoryExtensions.AsSpan(outBuf, num2)); CNG.silk_CNG(this, silkDecoderControl, pOut, pOut_ptr, num); PLC.silk_PLC_glue_frames(this, pOut, pOut_ptr, num); lagPrev = silkDecoderControl.pitchL[nb_subfr - 1]; pN.Val = num; return 0; } } internal class SilkChannelEncoder { internal readonly int[] In_HP_State = new int[2]; internal int variable_HP_smth1_Q15; internal int variable_HP_smth2_Q15; internal readonly SilkLPState sLP = new SilkLPState(); internal readonly SilkVADState sVAD = new SilkVADState(); internal readonly SilkNSQState sNSQ = new SilkNSQState(); internal readonly short[] prev_NLSFq_Q15 = new short[16]; internal int speech_activity_Q8; internal int allow_bandwidth_switch; internal sbyte LBRRprevLastGainIndex; internal sbyte prevSignalType; internal int prevLag; internal int pitch_LPC_win_length; internal int max_pitch_lag; internal int API_fs_Hz; internal int prev_API_fs_Hz; internal int maxInternal_fs_Hz; internal int minInternal_fs_Hz; internal int desiredInternal_fs_Hz; internal int fs_kHz; internal int nb_subfr; internal int frame_length; internal int subfr_length; internal int ltp_mem_length; internal int la_pitch; internal int la_shape; internal int shapeWinLength; internal int TargetRate_bps; internal int PacketSize_ms; internal int PacketLoss_perc; internal int frameCounter; internal int Complexity; internal int nStatesDelayedDecision; internal int useInterpolatedNLSFs; internal int shapingLPCOrder; internal int predictLPCOrder; internal int pitchEstimationComplexity; internal int pitchEstimationLPCOrder; internal int pitchEstimationThreshold_Q16; internal int LTPQuantLowComplexity; internal int mu_LTP_Q9; internal int sum_log_gain_Q7; internal int NLSF_MSVQ_Survivors; internal int first_frame_after_reset; internal int controlled_since_last_payload; internal int warping_Q16; internal int useCBR; internal int prefillFlag; internal byte[] pitch_lag_low_bits_iCDF; internal byte[] pitch_contour_iCDF; internal NLSFCodebook psNLSF_CB; internal readonly int[] input_quality_bands_Q15 = new int[4]; internal int input_tilt_Q15; internal int SNR_dB_Q7; internal readonly sbyte[] VAD_flags = new sbyte[3]; internal sbyte LBRR_flag; internal readonly int[] LBRR_flags = new int[3]; internal readonly SideInfoIndices indices = new SideInfoIndices(); internal readonly sbyte[] pulses = new sbyte[320]; internal readonly short[] inputBuf = new short[322]; internal int inputBufIx; internal int nFramesPerPacket; internal int nFramesEncoded; internal int nChannelsAPI; internal int nChannelsInternal; internal int channelNb; internal int frames_since_onset; internal int ec_prevSignalType; internal short ec_prevLagIndex; internal readonly SilkResamplerState resampler_state = new SilkResamplerState(); internal int useDTX; internal int inDTX; internal int noSpeechCounter; internal int useInBandFEC; internal int LBRR_enabled; internal int LBRR_GainIncreases; internal readonly SideInfoIndices[] indices_LBRR = new SideInfoIndices[3]; internal readonly sbyte[][] pulses_LBRR = Arrays.InitTwoDimensionalArray(3, 320); internal readonly SilkShapeState sShape = new SilkShapeState(); internal readonly SilkPrefilterState sPrefilt = new SilkPrefilterState(); internal readonly short[] x_buf = new short[720]; internal int LTPCorr_Q15; internal SilkChannelEncoder() { for (int i = 0; i < 3; i++) { indices_LBRR[i] = new SideInfoIndices(); } } internal void Reset() { Arrays.MemSetInt(In_HP_State, 0, 2); variable_HP_smth1_Q15 = 0; variable_HP_smth2_Q15 = 0; sLP.Reset(); sVAD.Reset(); sNSQ.Reset(); Arrays.MemSetShort(prev_NLSFq_Q15, 0, 16); speech_activity_Q8 = 0; allow_bandwidth_switch = 0; LBRRprevLastGainIndex = 0; prevSignalType = 0; prevLag = 0; pitch_LPC_win_length = 0; max_pitch_lag = 0; API_fs_Hz = 0; prev_API_fs_Hz = 0; maxInternal_fs_Hz = 0; minInternal_fs_Hz = 0; desiredInternal_fs_Hz = 0; fs_kHz = 0; nb_subfr = 0; frame_length = 0; subfr_length = 0; ltp_mem_length = 0; la_pitch = 0; la_shape = 0; shapeWinLength = 0; TargetRate_bps = 0; PacketSize_ms = 0; PacketLoss_perc = 0; frameCounter = 0; Complexity = 0; nStatesDelayedDecision = 0; useInterpolatedNLSFs = 0; shapingLPCOrder = 0; predictLPCOrder = 0; pitchEstimationComplexity = 0; pitchEstimationLPCOrder = 0; pitchEstimationThreshold_Q16 = 0; LTPQuantLowComplexity = 0; mu_LTP_Q9 = 0; sum_log_gain_Q7 = 0; NLSF_MSVQ_Survivors = 0; first_frame_after_reset = 0; controlled_since_last_payload = 0; warping_Q16 = 0; useCBR = 0; prefillFlag = 0; pitch_lag_low_bits_iCDF = null; pitch_contour_iCDF = null; psNLSF_CB = null; Arrays.MemSetInt(input_quality_bands_Q15, 0, 4); input_tilt_Q15 = 0; SNR_dB_Q7 = 0; Arrays.MemSetSbyte(VAD_flags, 0, 3); LBRR_flag = 0; Arrays.MemSetInt(LBRR_flags, 0, 3); indices.Reset(); Arrays.MemSetSbyte(pulses, 0, 320); Arrays.MemSetShort(inputBuf, 0, 322); inputBufIx = 0; nFramesPerPacket = 0; nFramesEncoded = 0; nChannelsAPI = 0; nChannelsInternal = 0; channelNb = 0; frames_since_onset = 0; ec_prevSignalType = 0; ec_prevLagIndex = 0; resampler_state.Reset(); useDTX = 0; inDTX = 0; noSpeechCounter = 0; useInBandFEC = 0; LBRR_enabled = 0; LBRR_GainIncreases = 0; for (int i = 0; i < 3; i++) { indices_LBRR[i].Reset(); Arrays.MemSetSbyte(pulses_LBRR[i], 0, 320); } sShape.Reset(); sPrefilt.Reset(); Arrays.MemSetShort(x_buf, 0, 720); LTPCorr_Q15 = 0; } internal int silk_control_encoder(EncControlState encControl, int TargetRate_bps, int allow_bw_switch, int channelNb, int force_fs_kHz) { int result = SilkError.SILK_NO_ERROR; useDTX = encControl.useDTX; useCBR = encControl.useCBR; API_fs_Hz = encControl.API_sampleRate; maxInternal_fs_Hz = encControl.maxInternalSampleRate; minInternal_fs_Hz = encControl.minInternalSampleRate; desiredInternal_fs_Hz = encControl.desiredInternalSampleRate; useInBandFEC = encControl.useInBandFEC; nChannelsAPI = encControl.nChannelsAPI; nChannelsInternal = encControl.nChannelsInternal; allow_bandwidth_switch = allow_bw_switch; this.channelNb = channelNb; if (controlled_since_last_payload != 0 && prefillFlag == 0) { if (API_fs_Hz != prev_API_fs_Hz && fs_kHz > 0) { result = silk_setup_resamplers(fs_kHz); } return result; } int num = silk_control_audio_bandwidth(encControl); if (force_fs_kHz != 0) { num = force_fs_kHz; } result = silk_setup_resamplers(num); result = silk_setup_fs(num, encControl.payloadSize_ms); result = silk_setup_complexity(encControl.complexity); PacketLoss_perc = encControl.packetLossPercentage; result = silk_setup_LBRR(TargetRate_bps); controlled_since_last_payload = 1; return result; } private int silk_setup_resamplers(int fs_kHz) { int num = 0; if (this.fs_kHz != fs_kHz || prev_API_fs_Hz != API_fs_Hz) { if (this.fs_kHz == 0) { num += Resampler.silk_resampler_init(resampler_state, API_fs_Hz, fs_kHz * 1000, 1); } else { SilkResamplerState silkResamplerState = null; int num2 = Inlines.silk_LSHIFT(nb_subfr * 5, 1) + 5; int inLen = num2 * this.fs_kHz; silkResamplerState = new SilkResamplerState(); num += Resampler.silk_resampler_init(silkResamplerState, Inlines.silk_SMULBB(this.fs_kHz, 1000), API_fs_Hz, 0); int num3 = num2 * Inlines.silk_DIV32_16(API_fs_Hz, 1000); short[] array = new short[num3]; num += Resampler.silk_resampler(silkResamplerState, array, 0, x_buf, 0, inLen); num += Resampler.silk_resampler_init(resampler_state, API_fs_Hz, Inlines.silk_SMULBB(fs_kHz, 1000), 1); num += Resampler.silk_resampler(resampler_state, x_buf, 0, array, 0, num3); } } prev_API_fs_Hz = API_fs_Hz; return num; } private int silk_setup_fs(int fs_kHz, int PacketSize_ms) { int result = SilkError.SILK_NO_ERROR; if (PacketSize_ms != this.PacketSize_ms) { if (PacketSize_ms != 10 && PacketSize_ms != 20 && PacketSize_ms != 40 && PacketSize_ms != 60) { result = SilkError.SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; } if (PacketSize_ms <= 10) { nFramesPerPacket = 1; nb_subfr = ((PacketSize_ms != 10) ? 1 : 2); frame_length = Inlines.silk_SMULBB(PacketSize_ms, fs_kHz); pitch_LPC_win_length = Inlines.silk_SMULBB(14, fs_kHz); if (this.fs_kHz == 8) { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_NB_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_iCDF; } } else { nFramesPerPacket = Inlines.silk_DIV32_16(PacketSize_ms, 20); nb_subfr = 4; frame_length = Inlines.silk_SMULBB(20, fs_kHz); pitch_LPC_win_length = Inlines.silk_SMULBB(24, fs_kHz); if (this.fs_kHz == 8) { pitch_contour_iCDF = Tables.silk_pitch_contour_NB_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_iCDF; } } this.PacketSize_ms = PacketSize_ms; TargetRate_bps = 0; } if (this.fs_kHz != fs_kHz) { sShape.Reset(); sPrefilt.Reset(); sNSQ.Reset(); Arrays.MemSetShort(prev_NLSFq_Q15, 0, 16); Arrays.MemSetInt(sLP.In_LP_State, 0, 2); inputBufIx = 0; nFramesEncoded = 0; TargetRate_bps = 0; prevLag = 100; first_frame_after_reset = 1; sPrefilt.lagPrev = 100; sShape.LastGainIndex = 10; sNSQ.lagPrev = 100; sNSQ.prev_gain_Q16 = 65536; prevSignalType = 0; this.fs_kHz = fs_kHz; if (this.fs_kHz == 8) { if (nb_subfr == 4) { pitch_contour_iCDF = Tables.silk_pitch_contour_NB_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_NB_iCDF; } } else if (nb_subfr == 4) { pitch_contour_iCDF = Tables.silk_pitch_contour_iCDF; } else { pitch_contour_iCDF = Tables.silk_pitch_contour_10_ms_iCDF; } if (this.fs_kHz == 8 || this.fs_kHz == 12) { predictLPCOrder = 10; psNLSF_CB = Tables.silk_NLSF_CB_NB_MB; } else { predictLPCOrder = 16; psNLSF_CB = Tables.silk_NLSF_CB_WB; } subfr_length = 5 * fs_kHz; frame_length = Inlines.silk_SMULBB(subfr_length, nb_subfr); ltp_mem_length = Inlines.silk_SMULBB(20, fs_kHz); la_pitch = Inlines.silk_SMULBB(2, fs_kHz); max_pitch_lag = Inlines.silk_SMULBB(18, fs_kHz); if (nb_subfr == 4) { pitch_LPC_win_length = Inlines.silk_SMULBB(24, fs_kHz); } else { pitch_LPC_win_length = Inlines.silk_SMULBB(14, fs_kHz); } if (this.fs_kHz == 16) { mu_LTP_Q9 = 10; pitch_lag_low_bits_iCDF = Tables.silk_uniform8_iCDF; } else if (this.fs_kHz == 12) { mu_LTP_Q9 = 13; pitch_lag_low_bits_iCDF = Tables.silk_uniform6_iCDF; } else { mu_LTP_Q9 = 15; pitch_lag_low_bits_iCDF = Tables.silk_uniform4_iCDF; } } return result; } private int silk_setup_complexity(int Complexity) { if (Complexity < 2) { pitchEstimationComplexity = 0; pitchEstimationThreshold_Q16 = 52429; pitchEstimationLPCOrder = 6; shapingLPCOrder = 8; la_shape = 3 * fs_kHz; nStatesDelayedDecision = 1; useInterpolatedNLSFs = 0; LTPQuantLowComplexity = 1; NLSF_MSVQ_Survivors = 2; warping_Q16 = 0; } else if (Complexity < 4) { pitchEstimationComplexity = 1; pitchEstimationThreshold_Q16 = 49807; pitchEstimationLPCOrder = 8; shapingLPCOrder = 10; la_shape = 5 * fs_kHz; nStatesDelayedDecision = 1; useInterpolatedNLSFs = 0; LTPQuantLowComplexity = 0; NLSF_MSVQ_Survivors = 4; warping_Q16 = 0; } else if (Complexity < 6) { pitchEstimationComplexity = 1; pitchEstimationThreshold_Q16 = 48497; pitchEstimationLPCOrder = 10; shapingLPCOrder = 12; la_shape = 5 * fs_kHz; nStatesDelayedDecision = 2; useInterpolatedNLSFs = 1; LTPQuantLowComplexity = 0; NLSF_MSVQ_Survivors = 8; warping_Q16 = fs_kHz * 983; } else if (Complexity < 8) { pitchEstimationComplexity = 1; pitchEstimationThreshold_Q16 = 47186; pitchEstimationLPCOrder = 12; shapingLPCOrder = 14; la_shape = 5 * fs_kHz; nStatesDelayedDecision = 3; useInterpolatedNLSFs = 1; LTPQuantLowComplexity = 0; NLSF_MSVQ_Survivors = 16; warping_Q16 = fs_kHz * 983; } else { pitchEstimationComplexity = 2; pitchEstimationThreshold_Q16 = 45875; pitchEstimationLPCOrder = 16; shapingLPCOrder = 16; la_shape = 5 * fs_kHz; nStatesDelayedDecision = 4; useInterpolatedNLSFs = 1; LTPQuantLowComplexity = 0; NLSF_MSVQ_Survivors = 32; warping_Q16 = fs_kHz * 983; } pitchEstimationLPCOrder = Inlines.silk_min_int(pitchEstimationLPCOrder, predictLPCOrder); shapeWinLength = 5 * fs_kHz + 2 * la_shape; this.Complexity = Complexity; return 0; } private int silk_setup_LBRR(int TargetRate_bps) { int sILK_NO_ERROR = SilkError.SILK_NO_ERROR; int lBRR_enabled = LBRR_enabled; LBRR_enabled = 0; if (useInBandFEC != 0 && PacketLoss_perc > 0) { int a = ((fs_kHz == 8) ? 12000 : ((fs_kHz != 12) ? 16000 : 14000)); a = Inlines.silk_SMULWB(Inlines.silk_MUL(a, 125 - Inlines.silk_min(PacketLoss_perc, 25)), 655); if (TargetRate_bps > a) { if (lBRR_enabled == 0) { LBRR_GainIncreases = 7; } else { LBRR_GainIncreases = Inlines.silk_max_int(7 - Inlines.silk_SMULWB(PacketLoss_perc, 26214), 2); } LBRR_enabled = 1; } } return sILK_NO_ERROR; } internal int silk_control_audio_bandwidth(EncControlState encControl) { int num = fs_kHz; int num2 = Inlines.silk_SMULBB(num, 1000); if (num2 == 0) { num2 = Inlines.silk_min(desiredInternal_fs_Hz, API_fs_Hz); num = Inlines.silk_DIV32_16(num2, 1000); } else if (num2 > API_fs_Hz || num2 > maxInternal_fs_Hz || num2 < minInternal_fs_Hz) { num2 = API_fs_Hz; num2 = Inlines.silk_min(num2, maxInternal_fs_Hz); num2 = Inlines.silk_max(num2, minInternal_fs_Hz); num = Inlines.silk_DIV32_16(num2, 1000); } else { if (sLP.transition_frame_no >= 256) { sLP.mode = 0; } if (allow_bandwidth_switch != 0 || encControl.opusCanSwitch != 0) { if (Inlines.silk_SMULBB(fs_kHz, 1000) > desiredInternal_fs_Hz) { if (sLP.mode == 0) { sLP.transition_frame_no = 256; Arrays.MemSetInt(sLP.In_LP_State, 0, 2); } if (encControl.opusCanSwitch != 0) { sLP.mode = 0; num = ((fs_kHz == 16) ? 12 : 8); } else if (sLP.transition_frame_no <= 0) { encControl.switchReady = 1; encControl.maxBits -= encControl.maxBits * 5 / (encControl.payloadSize_ms + 5); } else { sLP.mode = -2; } } else if (Inlines.silk_SMULBB(fs_kHz, 1000) < desiredInternal_fs_Hz) { if (encControl.opusCanSwitch != 0) { num = ((fs_kHz == 8) ? 12 : 16); sLP.transition_frame_no = 0; Arrays.MemSetInt(sLP.In_LP_State, 0, 2); sLP.mode = 1; } else if (sLP.mode == 0) { encControl.switchReady = 1; encControl.maxBits -= encControl.maxBits * 5 / (encControl.payloadSize_ms + 5); } else { sLP.mode = 1; } } else if (sLP.mode < 0) { sLP.mode = 1; } } } return num; } internal int silk_control_SNR(int TargetRate_bps) { int sILK_NO_ERROR = SilkError.SILK_NO_ERROR; TargetRate_bps = Inlines.silk_LIMIT(TargetRate_bps, 5000, 80000); if (TargetRate_bps != this.TargetRate_bps) { this.TargetRate_bps = TargetRate_bps; int[] array = ((fs_kHz == 8) ? Tables.silk_TargetRate_table_NB : ((fs_kHz != 12) ? Tables.silk_TargetRate_table_WB : Tables.silk_TargetRate_table_MB)); if (nb_subfr == 2) { TargetRate_bps -= 2200; } for (int i = 1; i < 8; i++) { if (TargetRate_bps <= array[i]) { int a = Inlines.silk_DIV32(Inlines.silk_LSHIFT(TargetRate_bps - array[i - 1], 6), array[i] - array[i - 1]); SNR_dB_Q7 = Inlines.silk_LSHIFT(Tables.silk_SNR_table_Q1[i - 1], 6) + Inlines.silk_MUL(a, Tables.silk_SNR_table_Q1[i] - Tables.silk_SNR_table_Q1[i - 1]); break; } } } return sILK_NO_ERROR; } internal void silk_encode_do_VAD() { VoiceActivityDetection.silk_VAD_GetSA_Q8(this, inputBuf, 1); if (speech_activity_Q8 < 13) { indices.signalType = 0; noSpeechCounter++; if (noSpeechCounter < 10) { inDTX = 0; } else if (noSpeechCounter > 30) { noSpeechCounter = 10; inDTX = 0; } VAD_flags[nFramesEncoded] = 0; } else { noSpeechCounter = 0; inDTX = 0; indices.signalType = 1; VAD_flags[nFramesEncoded] = 1; } } internal int silk_encode_frame(BoxedValueInt pnBytesOut, EntropyCoder psRangeEnc, Span encodedDataOut, int condCoding, int maxBits, int useCBR) { SilkEncoderControl silkEncoderControl = new SilkEncoderControl(); int result = 0; EntropyCoder entropyCoder = new EntropyCoder(); EntropyCoder entropyCoder2 = new EntropyCoder(); SilkNSQState silkNSQState = new SilkNSQState(); SilkNSQState silkNSQState2 = new SilkNSQState(); sbyte lastGainIndex = 0; int num2; int num3; int num4; int num = (num2 = (num3 = (num4 = 0))); indices.Seed = (sbyte)(frameCounter++ & 3); int num5 = ltp_mem_length; sLP.silk_LP_variable_cutoff(inputBuf, 1, frame_length); Arrays.MemCopy(inputBuf, 1, x_buf, num5 + 5 * fs_kHz, frame_length); if (prefillFlag == 0) { short[] array = new short[la_pitch + frame_length + ltp_mem_length]; int pitch_res_ptr = ltp_mem_length; FindPitchLags.silk_find_pitch_lags(this, silkEncoderControl, array, x_buf, num5); NoiseShapeAnalysis.silk_noise_shape_analysis(this, silkEncoderControl, array, pitch_res_ptr, x_buf, num5); FindPredCoefs.silk_find_pred_coefs(this, silkEncoderControl, array, x_buf, num5, condCoding); ProcessGains.silk_process_gains(this, silkEncoderControl, condCoding); int[] array2 = new int[frame_length]; Filters.silk_prefilter(this, silkEncoderControl, array2, x_buf, num5); silk_LBRR_encode(silkEncoderControl, array2, condCoding); int num6 = 6; short num7 = 256; int num8 = 0; int num9 = 0; int num10 = GainQuantization.silk_gains_ID(indices.GainsIndices, nb_subfr); int num11 = -1; int num12 = -1; entropyCoder.Assign(psRangeEnc); silkNSQState.Assign(sNSQ); sbyte seed = indices.Seed; short num13 = ec_prevLagIndex; int num14 = ec_prevSignalType; byte[] array3 = new byte[1275]; int num15 = 0; while (true) { int num16; if (num10 == num11) { num16 = num; } else if (num10 == num12) { num16 = num2; } else { if (num15 > 0) { psRangeEnc.Assign(entropyCoder); sNSQ.Assign(silkNSQState); indices.Seed = seed; ec_prevLagIndex = num13; ec_prevSignalType = num14; } if (nStatesDelayedDecision > 1 || warping_Q16 > 0) { sNSQ.silk_NSQ_del_dec(this, indices, array2, pulses, silkEncoderControl.PredCoef_Q12, silkEncoderControl.LTPCoef_Q14, silkEncoderControl.AR2_Q13, silkEncoderControl.HarmShapeGain_Q14, silkEncoderControl.Tilt_Q14, silkEncoderControl.LF_shp_Q14, silkEncoderControl.Gains_Q16, silkEncoderControl.pitchL, silkEncoderControl.Lambda_Q10, silkEncoderControl.LTP_scale_Q14); } else { sNSQ.silk_NSQ(this, indices, array2, pulses, silkEncoderControl.PredCoef_Q12, silkEncoderControl.LTPCoef_Q14, silkEncoderControl.AR2_Q13, silkEncoderControl.HarmShapeGain_Q14, silkEncoderControl.Tilt_Q14, silkEncoderControl.LF_shp_Q14, silkEncoderControl.Gains_Q16, silkEncoderControl.pitchL, silkEncoderControl.Lambda_Q10, silkEncoderControl.LTP_scale_Q14); } EncodeIndices.silk_encode_indices(this, psRangeEnc, encodedDataOut, nFramesEncoded, 0, condCoding); EncodePulses.silk_encode_pulses(psRangeEnc, encodedDataOut, indices.signalType, indices.quantOffsetType, pulses, frame_length); num16 = psRangeEnc.tell(); if (useCBR == 0 && num15 == 0 && num16 <= maxBits) { break; } } if (num15 == num6) { if (num8 != 0 && (num10 == num11 || num16 > maxBits)) { psRangeEnc.Assign(entropyCoder2); MemoryExtensions.AsSpan(array3, 0, (int)entropyCoder2.offs).CopyTo(encodedDataOut); sNSQ.Assign(silkNSQState2); sShape.LastGainIndex = lastGainIndex; } break; } if (num16 > maxBits) { if (num8 == 0 && num15 >= 2) { silkEncoderControl.Lambda_Q10 = Inlines.silk_ADD_RSHIFT32(silkEncoderControl.Lambda_Q10, silkEncoderControl.Lambda_Q10, 1); num9 = 0; num12 = -1; } else { num9 = 1; num2 = num16; num4 = num7; num12 = num10; } } else { if (num16 >= maxBits - 5) { break; } num8 = 1; num = num16; num3 = num7; if (num10 != num11) { num11 = num10; entropyCoder2.Assign(psRangeEnc); encodedDataOut.Slice(0, (int)psRangeEnc.offs).CopyTo(array3); silkNSQState2.Assign(sNSQ); lastGainIndex = sShape.LastGainIndex; } } if ((num8 & num9) == 0) { int a = Inlines.silk_log2lin(Inlines.silk_LSHIFT(num16 - maxBits, 7) / frame_length + 2048); a = Inlines.silk_min_32(a, 131072); if (num16 > maxBits) { a = Inlines.silk_max_32(a, 85197); } num7 = (short)Inlines.silk_SMULWB(a, num7); } else { num7 = (short)(num3 + Inlines.silk_DIV32_16(Inlines.silk_MUL(num4 - num3, maxBits - num), num2 - num)); if (num7 > Inlines.silk_ADD_RSHIFT32(num3, num4 - num3, 2)) { num7 = (short)Inlines.silk_ADD_RSHIFT32(num3, num4 - num3, 2); } else if (num7 < Inlines.silk_SUB_RSHIFT32(num4, num4 - num3, 2)) { num7 = (short)Inlines.silk_SUB_RSHIFT32(num4, num4 - num3, 2); } } for (int i = 0; i < nb_subfr; i++) { silkEncoderControl.Gains_Q16[i] = Inlines.silk_LSHIFT_SAT32(Inlines.silk_SMULWB(silkEncoderControl.GainsUnq_Q16[i], num7), 8); } sShape.LastGainIndex = silkEncoderControl.lastGainIndexPrev; BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(sShape.LastGainIndex); GainQuantization.silk_gains_quant(indices.GainsIndices, silkEncoderControl.Gains_Q16, boxedValueSbyte, (condCoding == 2) ? 1 : 0, nb_subfr); sShape.LastGainIndex = boxedValueSbyte.Val; num10 = GainQuantization.silk_gains_ID(indices.GainsIndices, nb_subfr); num15++; } } Arrays.MemMoveShort(x_buf, frame_length, 0, ltp_mem_length + 5 * fs_kHz); if (prefillFlag != 0) { pnBytesOut.Val = 0; return result; } prevLag = silkEncoderControl.pitchL[nb_subfr - 1]; prevSignalType = indices.signalType; first_frame_after_reset = 0; pnBytesOut.Val = Inlines.silk_RSHIFT(psRangeEnc.tell() + 7, 3); return result; } internal void silk_LBRR_encode(SilkEncoderControl thisCtrl, int[] xfw_Q3, int condCoding) { int[] array = new int[nb_subfr]; SideInfoIndices sideInfoIndices = indices_LBRR[nFramesEncoded]; SilkNSQState silkNSQState = new SilkNSQState(); if (LBRR_enabled != 0 && speech_activity_Q8 > 77) { LBRR_flags[nFramesEncoded] = 1; silkNSQState.Assign(sNSQ); sideInfoIndices.Assign(indices); Arrays.MemCopy(thisCtrl.Gains_Q16, 0, array, 0, nb_subfr); if (nFramesEncoded == 0 || LBRR_flags[nFramesEncoded - 1] == 0) { LBRRprevLastGainIndex = sShape.LastGainIndex; sideInfoIndices.GainsIndices[0] = (sbyte)(sideInfoIndices.GainsIndices[0] + LBRR_GainIncreases); sideInfoIndices.GainsIndices[0] = (sbyte)Inlines.silk_min_int(sideInfoIndices.GainsIndices[0], 63); } BoxedValueSbyte boxedValueSbyte = new BoxedValueSbyte(LBRRprevLastGainIndex); GainQuantization.silk_gains_dequant(thisCtrl.Gains_Q16, sideInfoIndices.GainsIndices, boxedValueSbyte, (condCoding == 2) ? 1 : 0, nb_subfr); LBRRprevLastGainIndex = boxedValueSbyte.Val; if (nStatesDelayedDecision > 1 || warping_Q16 > 0) { silkNSQState.silk_NSQ_del_dec(this, sideInfoIndices, xfw_Q3, pulses_LBRR[nFramesEncoded], thisCtrl.PredCoef_Q12, thisCtrl.LTPCoef_Q14, thisCtrl.AR2_Q13, thisCtrl.HarmShapeGain_Q14, thisCtrl.Tilt_Q14, thisCtrl.LF_shp_Q14, thisCtrl.Gains_Q16, thisCtrl.pitchL, thisCtrl.Lambda_Q10, thisCtrl.LTP_scale_Q14); } else { silkNSQState.silk_NSQ(this, sideInfoIndices, xfw_Q3, pulses_LBRR[nFramesEncoded], thisCtrl.PredCoef_Q12, thisCtrl.LTPCoef_Q14, thisCtrl.AR2_Q13, thisCtrl.HarmShapeGain_Q14, thisCtrl.Tilt_Q14, thisCtrl.LF_shp_Q14, thisCtrl.Gains_Q16, thisCtrl.pitchL, thisCtrl.Lambda_Q10, thisCtrl.LTP_scale_Q14); } Arrays.MemCopy(array, 0, thisCtrl.Gains_Q16, 0, nb_subfr); } } } internal class SilkDecoder { internal readonly SilkChannelDecoder[] channel_state = new SilkChannelDecoder[2]; internal readonly StereoDecodeState sStereo = new StereoDecodeState(); internal int nChannelsAPI; internal int nChannelsInternal; internal int prev_decode_only_middle; internal SilkDecoder() { for (int i = 0; i < 2; i++) { channel_state[i] = new SilkChannelDecoder(); } } internal void Reset() { for (int i = 0; i < 2; i++) { channel_state[i].Reset(); } sStereo.Reset(); nChannelsAPI = 0; nChannelsInternal = 0; prev_decode_only_middle = 0; } } internal class SilkDecoderControl { internal readonly int[] pitchL = new int[4]; internal readonly int[] Gains_Q16 = new int[4]; internal readonly short[][] PredCoef_Q12 = Arrays.InitTwoDimensionalArray(2, 16); internal readonly short[] LTPCoef_Q14 = new short[20]; internal int LTP_scale_Q14; internal void Reset() { Arrays.MemSetInt(pitchL, 0, 4); Arrays.MemSetInt(Gains_Q16, 0, 4); Arrays.MemSetShort(PredCoef_Q12[0], 0, 16); Arrays.MemSetShort(PredCoef_Q12[1], 0, 16); Arrays.MemSetShort(LTPCoef_Q14, 0, 20); LTP_scale_Q14 = 0; } } internal class SilkEncoder { internal readonly SilkChannelEncoder[] state_Fxx = new SilkChannelEncoder[2]; internal readonly StereoEncodeState sStereo = new StereoEncodeState(); internal int nBitsUsedLBRR; internal int nBitsExceeded; internal int nChannelsAPI; internal int nChannelsInternal; internal int nPrevChannelsInternal; internal int timeSinceSwitchAllowed_ms; internal int allowBandwidthSwitch; internal int prev_decode_only_middle; internal SilkEncoder() { for (int i = 0; i < 2; i++) { state_Fxx[i] = new SilkChannelEncoder(); } } internal void Reset() { for (int i = 0; i < 2; i++) { state_Fxx[i].Reset(); } sStereo.Reset(); nBitsUsedLBRR = 0; nBitsExceeded = 0; nChannelsAPI = 0; nChannelsInternal = 0; nPrevChannelsInternal = 0; timeSinceSwitchAllowed_ms = 0; allowBandwidthSwitch = 0; prev_decode_only_middle = 0; } internal static int silk_init_encoder(SilkChannelEncoder psEnc) { psEnc.Reset(); psEnc.variable_HP_smth1_Q15 = Inlines.silk_LSHIFT(Inlines.silk_lin2log(3932160) - 2048, 8); psEnc.variable_HP_smth2_Q15 = psEnc.variable_HP_smth1_Q15; psEnc.first_frame_after_reset = 1; return 0 + VoiceActivityDetection.silk_VAD_Init(psEnc.sVAD); } } internal class SilkEncoderControl { internal readonly int[] Gains_Q16 = new int[4]; internal readonly short[][] PredCoef_Q12 = Arrays.InitTwoDimensionalArray(2, 16); internal readonly short[] LTPCoef_Q14 = new short[20]; internal int LTP_scale_Q14; internal readonly int[] pitchL = new int[4]; internal readonly short[] AR1_Q13 = new short[64]; internal readonly short[] AR2_Q13 = new short[64]; internal readonly int[] LF_shp_Q14 = new int[4]; internal readonly int[] GainsPre_Q14 = new int[4]; internal readonly int[] HarmBoost_Q14 = new int[4]; internal readonly int[] Tilt_Q14 = new int[4]; internal readonly int[] HarmShapeGain_Q14 = new int[4]; internal int Lambda_Q10; internal int input_quality_Q14; internal int coding_quality_Q14; internal int sparseness_Q8; internal int predGain_Q16; internal int LTPredCodGain_Q7; internal readonly int[] ResNrg = new int[4]; internal readonly int[] ResNrgQ = new int[4]; internal readonly int[] GainsUnq_Q16 = new int[4]; internal sbyte lastGainIndexPrev; internal void Reset() { Arrays.MemSetInt(Gains_Q16, 0, 4); Arrays.MemSetShort(PredCoef_Q12[0], 0, 16); Arrays.MemSetShort(PredCoef_Q12[1], 0, 16); Arrays.MemSetShort(LTPCoef_Q14, 0, 20); LTP_scale_Q14 = 0; Arrays.MemSetInt(pitchL, 0, 4); Arrays.MemSetShort(AR1_Q13, 0, 64); Arrays.MemSetShort(AR2_Q13, 0, 64); Arrays.MemSetInt(LF_shp_Q14, 0, 4); Arrays.MemSetInt(GainsPre_Q14, 0, 4); Arrays.MemSetInt(HarmBoost_Q14, 0, 4); Arrays.MemSetInt(Tilt_Q14, 0, 4); Arrays.MemSetInt(HarmShapeGain_Q14, 0, 4); Lambda_Q10 = 0; input_quality_Q14 = 0; coding_quality_Q14 = 0; sparseness_Q8 = 0; predGain_Q16 = 0; LTPredCodGain_Q7 = 0; Arrays.MemSetInt(ResNrg, 0, 4); Arrays.MemSetInt(ResNrgQ, 0, 4); Arrays.MemSetInt(GainsUnq_Q16, 0, 4); lastGainIndexPrev = 0; } } internal class SilkLPState { internal readonly int[] In_LP_State = new int[2]; internal int transition_frame_no; internal int mode; internal void Reset() { In_LP_State[0] = 0; In_LP_State[1] = 0; transition_frame_no = 0; mode = 0; } internal void silk_LP_variable_cutoff(short[] frame, int frame_ptr, int frame_length) { int[] b_Q = new int[3]; int[] a_Q = new int[2]; int num = 0; int num2 = 0; if (mode != 0) { num = Inlines.silk_LSHIFT(256 - transition_frame_no, 10); num2 = Inlines.silk_RSHIFT(num, 16); num -= Inlines.silk_LSHIFT(num2, 16); Filters.silk_LP_interpolate_filter_taps(b_Q, a_Q, num2, num); transition_frame_no = Inlines.silk_LIMIT(transition_frame_no + mode, 0, 256); Filters.silk_biquad_alt(frame, frame_ptr, b_Q, a_Q, In_LP_State, frame, frame_ptr, frame_length, 1); } } } internal class SilkNSQState { private class NSQ_del_dec_struct { internal readonly int[] sLPC_Q14 = new int[80 + SilkConstants.NSQ_LPC_BUF_LENGTH]; internal readonly int[] RandState = new int[32]; internal readonly int[] Q_Q10 = new int[32]; internal readonly int[] Xq_Q14 = new int[32]; internal readonly int[] Pred_Q15 = new int[32]; internal readonly int[] Shape_Q14 = new int[32]; internal int[] sAR2_Q14; internal int LF_AR_Q14; internal int Seed; internal int SeedInit; internal int RD_Q10; internal NSQ_del_dec_struct(int shapingOrder) { sAR2_Q14 = new int[shapingOrder]; } internal void PartialCopyFrom(NSQ_del_dec_struct other, int q14Offset) { Buffer.BlockCopy(other.sLPC_Q14, q14Offset * 4, sLPC_Q14, q14Offset * 4, (80 + SilkConstants.NSQ_LPC_BUF_LENGTH - q14Offset) * 4); Buffer.BlockCopy(other.RandState, 0, RandState, 0, 128); Buffer.BlockCopy(other.Q_Q10, 0, Q_Q10, 0, 128); Buffer.BlockCopy(other.Xq_Q14, 0, Xq_Q14, 0, 128); Buffer.BlockCopy(other.Pred_Q15, 0, Pred_Q15, 0, 128); Buffer.BlockCopy(other.Shape_Q14, 0, Shape_Q14, 0, 128); Buffer.BlockCopy(other.sAR2_Q14, 0, sAR2_Q14, 0, sAR2_Q14.Length * 4); LF_AR_Q14 = other.LF_AR_Q14; Seed = other.Seed; SeedInit = other.SeedInit; RD_Q10 = other.RD_Q10; } internal void Assign(NSQ_del_dec_struct other) { PartialCopyFrom(other, 0); } } private struct NSQ_sample_struct { internal int Q_Q10; internal int RD_Q10; internal int xq_Q14; internal int LF_AR_Q14; internal int sLTP_shp_Q14; internal int LPC_exc_Q14; } internal readonly short[] xq = new short[640]; internal readonly int[] sLTP_shp_Q14 = new int[640]; internal readonly int[] sLPC_Q14 = new int[80 + SilkConstants.NSQ_LPC_BUF_LENGTH]; internal readonly int[] sAR2_Q14 = new int[16]; internal int sLF_AR_shp_Q14; internal int lagPrev; internal int sLTP_buf_idx; internal int sLTP_shp_buf_idx; internal int rand_seed; internal int prev_gain_Q16; internal int rewhite_flag; internal void Reset() { Arrays.MemSetShort(xq, 0, 640); Arrays.MemSetInt(sLTP_shp_Q14, 0, 640); Arrays.MemSetInt(sLPC_Q14, 0, 80 + SilkConstants.NSQ_LPC_BUF_LENGTH); Arrays.MemSetInt(sAR2_Q14, 0, 16); sLF_AR_shp_Q14 = 0; lagPrev = 0; sLTP_buf_idx = 0; sLTP_shp_buf_idx = 0; rand_seed = 0; prev_gain_Q16 = 0; rewhite_flag = 0; } internal void Assign(SilkNSQState other) { sLF_AR_shp_Q14 = other.sLF_AR_shp_Q14; lagPrev = other.lagPrev; sLTP_buf_idx = other.sLTP_buf_idx; sLTP_shp_buf_idx = other.sLTP_shp_buf_idx; rand_seed = other.rand_seed; prev_gain_Q16 = other.prev_gain_Q16; rewhite_flag = other.rewhite_flag; Arrays.MemCopy(other.xq, 0, xq, 0, 640); Arrays.MemCopy(other.sLTP_shp_Q14, 0, sLTP_shp_Q14, 0, 640); Arrays.MemCopy(other.sLPC_Q14, 0, sLPC_Q14, 0, 80 + SilkConstants.NSQ_LPC_BUF_LENGTH); Arrays.MemCopy(other.sAR2_Q14, 0, sAR2_Q14, 0, 16); } internal void silk_NSQ(SilkChannelEncoder psEncC, SideInfoIndices psIndices, int[] x_Q3, sbyte[] pulses, short[][] PredCoef_Q12, short[] LTPCoef_Q14, short[] AR2_Q13, int[] HarmShapeGain_Q14, int[] Tilt_Q14, int[] LF_shp_Q14, int[] Gains_Q16, int[] pitchL, int Lambda_Q10, int LTP_scale_Q14) { int num = 0; int num2 = 0; rand_seed = psIndices.Seed; int num3 = lagPrev; int offset_Q = Tables.silk_Quantization_Offsets_Q10[psIndices.signalType >> 1][psIndices.quantOffsetType]; int num4 = ((psIndices.NLSFInterpCoef_Q2 != 4) ? 1 : 0); int[] sLTP_Q = new int[psEncC.ltp_mem_length + psEncC.frame_length]; short[] array = new short[psEncC.ltp_mem_length + psEncC.frame_length]; int[] x_sc_Q = new int[psEncC.subfr_length]; sLTP_shp_buf_idx = psEncC.ltp_mem_length; sLTP_buf_idx = psEncC.ltp_mem_length; int num5 = psEncC.ltp_mem_length; for (int i = 0; i < psEncC.nb_subfr; i++) { int num6 = (i >> 1) | (1 - num4); int b_Q14_ptr = i * 5; int aR_shp_Q13_ptr = i * 16; int num7 = Inlines.silk_RSHIFT(HarmShapeGain_Q14[i], 2); num7 |= Inlines.silk_LSHIFT(Inlines.silk_RSHIFT(HarmShapeGain_Q14[i], 1), 16); rewhite_flag = 0; if (psIndices.signalType == 2) { num3 = pitchL[i]; if ((i & (3 - Inlines.silk_LSHIFT(num4, 1))) == 0) { int num8 = psEncC.ltp_mem_length - num3 - psEncC.predictLPCOrder - 2; Filters.silk_LPC_analysis_filter(array, num8, xq, num8 + i * psEncC.subfr_length, PredCoef_Q12[num6], 0, psEncC.ltp_mem_length - num8, psEncC.predictLPCOrder); rewhite_flag = 1; sLTP_buf_idx = psEncC.ltp_mem_length; } } silk_nsq_scale_states(psEncC, x_Q3, num2, x_sc_Q, array, sLTP_Q, i, LTP_scale_Q14, Gains_Q16, pitchL, psIndices.signalType); silk_noise_shape_quantizer(psIndices.signalType, x_sc_Q, pulses, num, xq, num5, sLTP_Q, PredCoef_Q12[num6], LTPCoef_Q14, b_Q14_ptr, AR2_Q13, aR_shp_Q13_ptr, num3, num7, Tilt_Q14[i], LF_shp_Q14[i], Gains_Q16[i], Lambda_Q10, offset_Q, psEncC.subfr_length, psEncC.shapingLPCOrder, psEncC.predictLPCOrder); num2 += psEncC.subfr_length; num += psEncC.subfr_length; num5 += psEncC.subfr_length; } lagPrev = pitchL[psEncC.nb_subfr - 1]; Arrays.MemMoveShort(xq, psEncC.frame_length, 0, psEncC.ltp_mem_length); Arrays.MemMoveInt(sLTP_shp_Q14, psEncC.frame_length, 0, psEncC.ltp_mem_length); } private void silk_noise_shape_quantizer(int signalType, int[] x_sc_Q10, sbyte[] pulses, int pulses_ptr, short[] xq, int xq_ptr, int[] sLTP_Q15, short[] a_Q12, short[] b_Q14, int b_Q14_ptr, short[] AR_shp_Q13, int AR_shp_Q13_ptr, int lag, int HarmShapeFIRPacked_Q14, int Tilt_Q14, int LF_shp_Q14, int Gain_Q16, int Lambda_Q10, int offset_Q10, int length, int shapingLPCOrder, int predictLPCOrder) { int num = sLTP_shp_buf_idx - lag + 1; int num2 = sLTP_buf_idx - lag + 2; int b = Inlines.silk_RSHIFT(Gain_Q16, 6); int num3 = SilkConstants.NSQ_LPC_BUF_LENGTH - 1; for (int i = 0; i < length; i++) { rand_seed = Inlines.silk_RAND(rand_seed); int a = Inlines.silk_RSHIFT(predictLPCOrder, 1); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3], a_Q12[0]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 1], a_Q12[1]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 2], a_Q12[2]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 3], a_Q12[3]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 4], a_Q12[4]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 5], a_Q12[5]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 6], a_Q12[6]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 7], a_Q12[7]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 8], a_Q12[8]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 9], a_Q12[9]); if (predictLPCOrder == 16) { a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 10], a_Q12[10]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 11], a_Q12[11]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 12], a_Q12[12]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 13], a_Q12[13]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 14], a_Q12[14]); a = Inlines.silk_SMLAWB(a, sLPC_Q14[num3 - 15], a_Q12[15]); } int a2; if (signalType == 2) { a2 = 2; a2 = Inlines.silk_SMLAWB(a2, sLTP_Q15[num2], b_Q14[b_Q14_ptr]); a2 = Inlines.silk_SMLAWB(a2, sLTP_Q15[num2 - 1], b_Q14[b_Q14_ptr + 1]); a2 = Inlines.silk_SMLAWB(a2, sLTP_Q15[num2 - 2], b_Q14[b_Q14_ptr + 2]); a2 = Inlines.silk_SMLAWB(a2, sLTP_Q15[num2 - 3], b_Q14[b_Q14_ptr + 3]); a2 = Inlines.silk_SMLAWB(a2, sLTP_Q15[num2 - 4], b_Q14[b_Q14_ptr + 4]); num2++; } else { a2 = 0; } int num4 = sLPC_Q14[num3]; int num5 = sAR2_Q14[0]; sAR2_Q14[0] = num4; int a3 = Inlines.silk_RSHIFT(shapingLPCOrder, 1); a3 = Inlines.silk_SMLAWB(a3, num4, AR_shp_Q13[AR_shp_Q13_ptr]); for (int j = 2; j < shapingLPCOrder; j += 2) { num4 = sAR2_Q14[j - 1]; sAR2_Q14[j - 1] = num5; a3 = Inlines.silk_SMLAWB(a3, num5, AR_shp_Q13[AR_shp_Q13_ptr + j - 1]); num5 = sAR2_Q14[j]; sAR2_Q14[j] = num4; a3 = Inlines.silk_SMLAWB(a3, num4, AR_shp_Q13[AR_shp_Q13_ptr + j]); } sAR2_Q14[shapingLPCOrder - 1] = num5; a3 = Inlines.silk_SMLAWB(a3, num5, AR_shp_Q13[AR_shp_Q13_ptr + shapingLPCOrder - 1]); a3 = Inlines.silk_LSHIFT32(a3, 1); a3 = Inlines.silk_SMLAWB(a3, sLF_AR_shp_Q14, Tilt_Q14); int a4 = Inlines.silk_SMULWB(sLTP_shp_Q14[sLTP_shp_buf_idx - 1], LF_shp_Q14); a4 = Inlines.silk_SMLAWT(a4, sLF_AR_shp_Q14, LF_shp_Q14); num5 = Inlines.silk_SUB32(Inlines.silk_LSHIFT32(a, 2), a3); num5 = Inlines.silk_SUB32(num5, a4); if (lag > 0) { int a5 = Inlines.silk_SMULWB(Inlines.silk_ADD32(sLTP_shp_Q14[num], sLTP_shp_Q14[num - 2]), HarmShapeFIRPacked_Q14); a5 = Inlines.silk_SMLAWT(a5, sLTP_shp_Q14[num - 1], HarmShapeFIRPacked_Q14); a5 = Inlines.silk_LSHIFT(a5, 1); num++; num4 = Inlines.silk_SUB32(a2, a5); num5 = Inlines.silk_ADD_LSHIFT32(num4, num5, 1); num5 = Inlines.silk_RSHIFT_ROUND(num5, 3); } else { num5 = Inlines.silk_RSHIFT_ROUND(num5, 2); } int num6 = Inlines.silk_SUB32(x_sc_Q10[i], num5); if (rand_seed < 0) { num6 = -num6; } num6 = Inlines.silk_LIMIT_32(num6, -31744, 30720); int a6 = Inlines.silk_SUB32(num6, offset_Q10); int num7 = Inlines.silk_RSHIFT(a6, 10); int num8; int a7; int a8; if (num7 > 0) { a6 = Inlines.silk_SUB32(Inlines.silk_LSHIFT(num7, 10), 80); a6 = Inlines.silk_ADD32(a6, offset_Q10); num8 = Inlines.silk_ADD32(a6, 1024); a7 = Inlines.silk_SMULBB(a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num8, Lambda_Q10); } else { switch (num7) { case 0: a6 = offset_Q10; num8 = Inlines.silk_ADD32(a6, 944); a7 = Inlines.silk_SMULBB(a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num8, Lambda_Q10); break; case -1: num8 = offset_Q10; a6 = Inlines.silk_SUB32(num8, 944); a7 = Inlines.silk_SMULBB(-a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num8, Lambda_Q10); break; default: a6 = Inlines.silk_ADD32(Inlines.silk_LSHIFT(num7, 10), 80); a6 = Inlines.silk_ADD32(a6, offset_Q10); num8 = Inlines.silk_ADD32(a6, 1024); a7 = Inlines.silk_SMULBB(-a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(-num8, Lambda_Q10); break; } } int num9 = Inlines.silk_SUB32(num6, a6); a7 = Inlines.silk_SMLABB(a7, num9, num9); num9 = Inlines.silk_SUB32(num6, num8); a8 = Inlines.silk_SMLABB(a8, num9, num9); if (a8 < a7) { a6 = num8; } pulses[pulses_ptr + i] = (sbyte)Inlines.silk_RSHIFT_ROUND(a6, 10); int num10 = Inlines.silk_LSHIFT(a6, 4); if (rand_seed < 0) { num10 = -num10; } int a9 = Inlines.silk_ADD_LSHIFT32(num10, a2, 1); int num11 = Inlines.silk_ADD_LSHIFT32(a9, a, 4); xq[xq_ptr + i] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(num11, b), 8)); num3++; sLPC_Q14[num3] = num11; int a10 = (sLF_AR_shp_Q14 = Inlines.silk_SUB_LSHIFT32(num11, a3, 2)); sLTP_shp_Q14[sLTP_shp_buf_idx] = Inlines.silk_SUB_LSHIFT32(a10, a4, 2); sLTP_Q15[sLTP_buf_idx] = Inlines.silk_LSHIFT(a9, 1); sLTP_shp_buf_idx++; sLTP_buf_idx++; rand_seed = Inlines.silk_ADD32_ovflw(rand_seed, pulses[pulses_ptr + i]); } Arrays.MemCopy(sLPC_Q14, length, sLPC_Q14, 0, SilkConstants.NSQ_LPC_BUF_LENGTH); } private void silk_nsq_scale_states(SilkChannelEncoder psEncC, int[] x_Q3, int x_Q3_ptr, int[] x_sc_Q10, short[] sLTP, int[] sLTP_Q15, int subfr, int LTP_scale_Q14, int[] Gains_Q16, int[] pitchL, int signal_type) { int num = pitchL[subfr]; int num2 = Inlines.silk_INVERSE32_varQ(Inlines.silk_max(Gains_Q16[subfr], 1), 47); int num3 = ((Gains_Q16[subfr] == prev_gain_Q16) ? 65536 : Inlines.silk_DIV32_varQ(prev_gain_Q16, Gains_Q16[subfr], 16)); int b = Inlines.silk_RSHIFT_ROUND(num2, 8); for (int i = 0; i < psEncC.subfr_length; i++) { x_sc_Q10[i] = Inlines.silk_SMULWW(x_Q3[x_Q3_ptr + i], b); } prev_gain_Q16 = Gains_Q16[subfr]; if (rewhite_flag != 0) { if (subfr == 0) { num2 = Inlines.silk_LSHIFT(Inlines.silk_SMULWB(num2, LTP_scale_Q14), 2); } for (int i = sLTP_buf_idx - num - 2; i < sLTP_buf_idx; i++) { sLTP_Q15[i] = Inlines.silk_SMULWB(num2, sLTP[i]); } } if (num3 == 65536) { return; } for (int i = sLTP_shp_buf_idx - psEncC.ltp_mem_length; i < sLTP_shp_buf_idx; i++) { sLTP_shp_Q14[i] = Inlines.silk_SMULWW(num3, sLTP_shp_Q14[i]); } if (signal_type == 2 && rewhite_flag == 0) { for (int i = sLTP_buf_idx - num - 2; i < sLTP_buf_idx; i++) { sLTP_Q15[i] = Inlines.silk_SMULWW(num3, sLTP_Q15[i]); } } sLF_AR_shp_Q14 = Inlines.silk_SMULWW(num3, sLF_AR_shp_Q14); for (int i = 0; i < SilkConstants.NSQ_LPC_BUF_LENGTH; i++) { sLPC_Q14[i] = Inlines.silk_SMULWW(num3, sLPC_Q14[i]); } for (int i = 0; i < 16; i++) { sAR2_Q14[i] = Inlines.silk_SMULWW(num3, sAR2_Q14[i]); } } internal void silk_NSQ_del_dec(SilkChannelEncoder psEncC, SideInfoIndices psIndices, int[] x_Q3, sbyte[] pulses, short[][] PredCoef_Q12, short[] LTPCoef_Q14, short[] AR2_Q13, int[] HarmShapeGain_Q14, int[] Tilt_Q14, int[] LF_shp_Q14, int[] Gains_Q16, int[] pitchL, int Lambda_Q10, int LTP_scale_Q14) { int num = 0; int num2 = 0; int num3 = lagPrev; NSQ_del_dec_struct[] array = new NSQ_del_dec_struct[psEncC.nStatesDelayedDecision]; for (int i = 0; i < psEncC.nStatesDelayedDecision; i++) { array[i] = new NSQ_del_dec_struct(psEncC.shapingLPCOrder); } NSQ_del_dec_struct nSQ_del_dec_struct; for (int j = 0; j < psEncC.nStatesDelayedDecision; j++) { nSQ_del_dec_struct = array[j]; nSQ_del_dec_struct.Seed = (j + psIndices.Seed) & 3; nSQ_del_dec_struct.SeedInit = nSQ_del_dec_struct.Seed; nSQ_del_dec_struct.RD_Q10 = 0; nSQ_del_dec_struct.LF_AR_Q14 = sLF_AR_shp_Q14; nSQ_del_dec_struct.Shape_Q14[0] = sLTP_shp_Q14[psEncC.ltp_mem_length - 1]; Arrays.MemCopy(sLPC_Q14, 0, nSQ_del_dec_struct.sLPC_Q14, 0, SilkConstants.NSQ_LPC_BUF_LENGTH); Arrays.MemCopy(sAR2_Q14, 0, nSQ_del_dec_struct.sAR2_Q14, 0, psEncC.shapingLPCOrder); } int offset_Q = Tables.silk_Quantization_Offsets_Q10[psIndices.signalType >> 1][psIndices.quantOffsetType]; int num4 = 0; int num5 = Inlines.silk_min_int(32, psEncC.subfr_length); if (psIndices.signalType == 2) { for (int j = 0; j < psEncC.nb_subfr; j++) { num5 = Inlines.silk_min_int(num5, pitchL[j] - 2 - 1); } } else if (num3 > 0) { num5 = Inlines.silk_min_int(num5, num3 - 2 - 1); } int num6 = ((psIndices.NLSFInterpCoef_Q2 != 4) ? 1 : 0); int[] sLTP_Q = new int[psEncC.ltp_mem_length + psEncC.frame_length]; short[] array2 = new short[psEncC.ltp_mem_length + psEncC.frame_length]; int[] array3 = new int[psEncC.subfr_length]; int[] delayedGain_Q = new int[32]; int num7 = psEncC.ltp_mem_length; sLTP_shp_buf_idx = psEncC.ltp_mem_length; sLTP_buf_idx = psEncC.ltp_mem_length; int num8 = 0; int rD_Q; int num11; int num12; for (int j = 0; j < psEncC.nb_subfr; j++) { int num9 = (j >> 1) | (1 - num6); int num10 = Inlines.silk_RSHIFT(HarmShapeGain_Q14[j], 2); num10 |= Inlines.silk_LSHIFT(Inlines.silk_RSHIFT(HarmShapeGain_Q14[j], 1), 16); rewhite_flag = 0; if (psIndices.signalType == 2) { num3 = pitchL[j]; if ((j & (3 - Inlines.silk_LSHIFT(num6, 1))) == 0) { if (j == 2) { rD_Q = array[0].RD_Q10; num11 = 0; for (int k = 1; k < psEncC.nStatesDelayedDecision; k++) { if (array[k].RD_Q10 < rD_Q) { rD_Q = array[k].RD_Q10; num11 = k; } } for (int k = 0; k < psEncC.nStatesDelayedDecision; k++) { if (k != num11) { array[k].RD_Q10 += 134217727; } } nSQ_del_dec_struct = array[num11]; num12 = num4 + num5; for (int k = 0; k < num5; k++) { num12 = (num12 - 1) & 0x1F; pulses[num + k - num5] = (sbyte)Inlines.silk_RSHIFT_ROUND(nSQ_del_dec_struct.Q_Q10[num12], 10); xq[num7 + k - num5] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(nSQ_del_dec_struct.Xq_Q14[num12], Gains_Q16[1]), 14)); sLTP_shp_Q14[sLTP_shp_buf_idx - num5 + k] = nSQ_del_dec_struct.Shape_Q14[num12]; } num8 = 0; } int num13 = psEncC.ltp_mem_length - num3 - psEncC.predictLPCOrder - 2; Filters.silk_LPC_analysis_filter(array2, num13, xq, num13 + j * psEncC.subfr_length, PredCoef_Q12[num9], 0, psEncC.ltp_mem_length - num13, psEncC.predictLPCOrder); sLTP_buf_idx = psEncC.ltp_mem_length; rewhite_flag = 1; } } silk_nsq_del_dec_scale_states(psEncC, array, x_Q3, num2, array3, array2, sLTP_Q, j, psEncC.nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices.signalType, num5); BoxedValueInt boxedValueInt = new BoxedValueInt(num4); silk_noise_shape_quantizer_del_dec(array, psIndices.signalType, array3, pulses, num, xq, num7, sLTP_Q, delayedGain_Q, PredCoef_Q12[num9], LTPCoef_Q14, j * 5, AR2_Q13, j * 16, num3, num10, Tilt_Q14[j], LF_shp_Q14[j], Gains_Q16[j], Lambda_Q10, offset_Q, psEncC.subfr_length, num8++, psEncC.shapingLPCOrder, psEncC.predictLPCOrder, psEncC.warping_Q16, psEncC.nStatesDelayedDecision, boxedValueInt, num5); num4 = boxedValueInt.Val; num2 += psEncC.subfr_length; num += psEncC.subfr_length; num7 += psEncC.subfr_length; } rD_Q = array[0].RD_Q10; num11 = 0; for (int j = 1; j < psEncC.nStatesDelayedDecision; j++) { if (array[j].RD_Q10 < rD_Q) { rD_Q = array[j].RD_Q10; num11 = j; } } nSQ_del_dec_struct = array[num11]; psIndices.Seed = (sbyte)nSQ_del_dec_struct.SeedInit; num12 = num4 + num5; int b = Inlines.silk_RSHIFT32(Gains_Q16[psEncC.nb_subfr - 1], 6); for (int k = 0; k < num5; k++) { num12 = (num12 - 1) & 0x1F; pulses[num + k - num5] = (sbyte)Inlines.silk_RSHIFT_ROUND(nSQ_del_dec_struct.Q_Q10[num12], 10); xq[num7 + k - num5] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(nSQ_del_dec_struct.Xq_Q14[num12], b), 8)); sLTP_shp_Q14[sLTP_shp_buf_idx - num5 + k] = nSQ_del_dec_struct.Shape_Q14[num12]; } Arrays.MemCopy(nSQ_del_dec_struct.sLPC_Q14, psEncC.subfr_length, sLPC_Q14, 0, SilkConstants.NSQ_LPC_BUF_LENGTH); Arrays.MemCopy(nSQ_del_dec_struct.sAR2_Q14, 0, sAR2_Q14, 0, psEncC.shapingLPCOrder); sLF_AR_shp_Q14 = nSQ_del_dec_struct.LF_AR_Q14; lagPrev = pitchL[psEncC.nb_subfr - 1]; Arrays.MemMoveShort(xq, psEncC.frame_length, 0, psEncC.ltp_mem_length); Arrays.MemMoveInt(sLTP_shp_Q14, psEncC.frame_length, 0, psEncC.ltp_mem_length); } private void silk_noise_shape_quantizer_del_dec(NSQ_del_dec_struct[] psDelDec, int signalType, int[] x_Q10, sbyte[] pulses, int pulses_ptr, short[] xq, int xq_ptr, int[] sLTP_Q15, int[] delayedGain_Q10, short[] a_Q12, short[] b_Q14, int b_Q14_ptr, short[] AR_shp_Q13, int AR_shp_Q13_ptr, int lag, int HarmShapeFIRPacked_Q14, int Tilt_Q14, int LF_shp_Q14, int Gain_Q16, int Lambda_Q10, int offset_Q10, int length, int subfr, int shapingLPCOrder, int predictLPCOrder, int warping_Q16, int nStatesDelayedDecision, BoxedValueInt smpl_buf_idx, int decisionDelay) { NSQ_sample_struct[] array = new NSQ_sample_struct[2 * nStatesDelayedDecision]; for (int i = 0; i < 2 * nStatesDelayedDecision; i++) { array[i] = default(NSQ_sample_struct); } int num = sLTP_shp_buf_idx - lag + 1; int num2 = sLTP_buf_idx - lag + 2; int num3 = Inlines.silk_RSHIFT(Gain_Q16, 6); for (int j = 0; j < length; j++) { int a; if (signalType == 2) { a = 2; a = Inlines.silk_SMLAWB(a, sLTP_Q15[num2], b_Q14[b_Q14_ptr]); a = Inlines.silk_SMLAWB(a, sLTP_Q15[num2 - 1], b_Q14[b_Q14_ptr + 1]); a = Inlines.silk_SMLAWB(a, sLTP_Q15[num2 - 2], b_Q14[b_Q14_ptr + 2]); a = Inlines.silk_SMLAWB(a, sLTP_Q15[num2 - 3], b_Q14[b_Q14_ptr + 3]); a = Inlines.silk_SMLAWB(a, sLTP_Q15[num2 - 4], b_Q14[b_Q14_ptr + 4]); a = Inlines.silk_LSHIFT(a, 1); num2++; } else { a = 0; } int a2; if (lag > 0) { a2 = Inlines.silk_SMULWB(Inlines.silk_ADD32(sLTP_shp_Q14[num], sLTP_shp_Q14[num - 2]), HarmShapeFIRPacked_Q14); a2 = Inlines.silk_SMLAWT(a2, sLTP_shp_Q14[num - 1], HarmShapeFIRPacked_Q14); a2 = Inlines.silk_SUB_LSHIFT32(a, a2, 2); num++; } else { a2 = 0; } NSQ_del_dec_struct nSQ_del_dec_struct; for (int k = 0; k < nStatesDelayedDecision; k++) { nSQ_del_dec_struct = psDelDec[k]; int[] array2 = nSQ_del_dec_struct.sAR2_Q14; int num4 = 2 * k; int num5 = num4 + 1; nSQ_del_dec_struct.Seed = Inlines.silk_RAND(nSQ_del_dec_struct.Seed); int num6 = SilkConstants.NSQ_LPC_BUF_LENGTH - 1 + j; int a3 = Inlines.silk_RSHIFT(predictLPCOrder, 1); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6], a_Q12[0]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 1], a_Q12[1]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 2], a_Q12[2]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 3], a_Q12[3]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 4], a_Q12[4]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 5], a_Q12[5]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 6], a_Q12[6]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 7], a_Q12[7]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 8], a_Q12[8]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 9], a_Q12[9]); if (predictLPCOrder == 16) { a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 10], a_Q12[10]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 11], a_Q12[11]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 12], a_Q12[12]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 13], a_Q12[13]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 14], a_Q12[14]); a3 = Inlines.silk_SMLAWB(a3, nSQ_del_dec_struct.sLPC_Q14[num6 - 15], a_Q12[15]); } a3 = Inlines.silk_LSHIFT(a3, 4); int num7 = Inlines.silk_SMLAWB(nSQ_del_dec_struct.sLPC_Q14[num6], array2[0], warping_Q16); int num8 = Inlines.silk_SMLAWB(array2[0], array2[1] - num7, warping_Q16); array2[0] = num7; int a4 = Inlines.silk_RSHIFT(shapingLPCOrder, 1); a4 = Inlines.silk_SMLAWB(a4, num7, AR_shp_Q13[AR_shp_Q13_ptr]); for (int l = 2; l < shapingLPCOrder; l += 2) { num7 = Inlines.silk_SMLAWB(array2[l - 1], array2[l] - num8, warping_Q16); array2[l - 1] = num8; a4 = Inlines.silk_SMLAWB(a4, num8, AR_shp_Q13[AR_shp_Q13_ptr + l - 1]); num8 = Inlines.silk_SMLAWB(array2[l], array2[l + 1] - num7, warping_Q16); array2[l] = num7; a4 = Inlines.silk_SMLAWB(a4, num7, AR_shp_Q13[AR_shp_Q13_ptr + l]); } array2[shapingLPCOrder - 1] = num8; a4 = Inlines.silk_SMLAWB(a4, num8, AR_shp_Q13[AR_shp_Q13_ptr + shapingLPCOrder - 1]); a4 = Inlines.silk_LSHIFT(a4, 1); a4 = Inlines.silk_SMLAWB(a4, nSQ_del_dec_struct.LF_AR_Q14, Tilt_Q14); a4 = Inlines.silk_LSHIFT(a4, 2); int a5 = Inlines.silk_SMULWB(nSQ_del_dec_struct.Shape_Q14[smpl_buf_idx.Val], LF_shp_Q14); a5 = Inlines.silk_SMLAWT(a5, nSQ_del_dec_struct.LF_AR_Q14, LF_shp_Q14); a5 = Inlines.silk_LSHIFT(a5, 2); num8 = Inlines.silk_ADD32(a4, a5); num7 = Inlines.silk_ADD32(a2, a3); num8 = Inlines.silk_SUB32(num7, num8); num8 = Inlines.silk_RSHIFT_ROUND(num8, 4); int num9 = Inlines.silk_SUB32(x_Q10[j], num8); if (nSQ_del_dec_struct.Seed < 0) { num9 = -num9; } num9 = Inlines.silk_LIMIT_32(num9, -31744, 30720); int a6 = Inlines.silk_SUB32(num9, offset_Q10); int num10 = Inlines.silk_RSHIFT(a6, 10); int num11; int a7; int a8; if (num10 > 0) { a6 = Inlines.silk_SUB32(Inlines.silk_LSHIFT(num10, 10), 80); a6 = Inlines.silk_ADD32(a6, offset_Q10); num11 = Inlines.silk_ADD32(a6, 1024); a7 = Inlines.silk_SMULBB(a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num11, Lambda_Q10); } else { switch (num10) { case 0: a6 = offset_Q10; num11 = Inlines.silk_ADD32(a6, 944); a7 = Inlines.silk_SMULBB(a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num11, Lambda_Q10); break; case -1: num11 = offset_Q10; a6 = Inlines.silk_SUB32(num11, 944); a7 = Inlines.silk_SMULBB(-a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(num11, Lambda_Q10); break; default: a6 = Inlines.silk_ADD32(Inlines.silk_LSHIFT(num10, 10), 80); a6 = Inlines.silk_ADD32(a6, offset_Q10); num11 = Inlines.silk_ADD32(a6, 1024); a7 = Inlines.silk_SMULBB(-a6, Lambda_Q10); a8 = Inlines.silk_SMULBB(-num11, Lambda_Q10); break; } } int num12 = Inlines.silk_SUB32(num9, a6); a7 = Inlines.silk_RSHIFT(Inlines.silk_SMLABB(a7, num12, num12), 10); num12 = Inlines.silk_SUB32(num9, num11); a8 = Inlines.silk_RSHIFT(Inlines.silk_SMLABB(a8, num12, num12), 10); if (a7 < a8) { array[num4].RD_Q10 = Inlines.silk_ADD32(nSQ_del_dec_struct.RD_Q10, a7); array[num5].RD_Q10 = Inlines.silk_ADD32(nSQ_del_dec_struct.RD_Q10, a8); array[num4].Q_Q10 = a6; array[num5].Q_Q10 = num11; } else { array[num4].RD_Q10 = Inlines.silk_ADD32(nSQ_del_dec_struct.RD_Q10, a8); array[num5].RD_Q10 = Inlines.silk_ADD32(nSQ_del_dec_struct.RD_Q10, a7); array[num4].Q_Q10 = num11; array[num5].Q_Q10 = a6; } int num13 = Inlines.silk_LSHIFT32(array[num4].Q_Q10, 4); if (nSQ_del_dec_struct.Seed < 0) { num13 = -num13; } int num14 = Inlines.silk_ADD32(num13, a); int num15 = Inlines.silk_ADD32(num14, a3); int num16 = Inlines.silk_SUB32(num15, a4); array[num4].sLTP_shp_Q14 = Inlines.silk_SUB32(num16, a5); array[num4].LF_AR_Q14 = num16; array[num4].LPC_exc_Q14 = num14; array[num4].xq_Q14 = num15; num13 = Inlines.silk_LSHIFT32(array[num5].Q_Q10, 4); if (nSQ_del_dec_struct.Seed < 0) { num13 = -num13; } num14 = Inlines.silk_ADD32(num13, a); num15 = Inlines.silk_ADD32(num14, a3); num16 = Inlines.silk_SUB32(num15, a4); array[num5].sLTP_shp_Q14 = Inlines.silk_SUB32(num16, a5); array[num5].LF_AR_Q14 = num16; array[num5].LPC_exc_Q14 = num14; array[num5].xq_Q14 = num15; } smpl_buf_idx.Val = (smpl_buf_idx.Val - 1) & 0x1F; int num17 = (smpl_buf_idx.Val + decisionDelay) & 0x1F; int rD_Q = array[0].RD_Q10; int num18 = 0; for (int k = 1; k < nStatesDelayedDecision; k++) { if (array[k * 2].RD_Q10 < rD_Q) { rD_Q = array[k * 2].RD_Q10; num18 = k; } } int num19 = psDelDec[num18].RandState[num17]; for (int k = 0; k < nStatesDelayedDecision; k++) { if (psDelDec[k].RandState[num17] != num19) { int num20 = k * 2; array[num20].RD_Q10 = Inlines.silk_ADD32(array[num20].RD_Q10, 134217727); array[num20 + 1].RD_Q10 = Inlines.silk_ADD32(array[num20 + 1].RD_Q10, 134217727); } } int rD_Q2 = array[0].RD_Q10; rD_Q = array[1].RD_Q10; int num21 = 0; int num22 = 0; for (int k = 1; k < nStatesDelayedDecision; k++) { int num23 = k * 2; if (array[num23].RD_Q10 > rD_Q2) { rD_Q2 = array[num23].RD_Q10; num21 = k; } if (array[num23 + 1].RD_Q10 < rD_Q) { rD_Q = array[num23 + 1].RD_Q10; num22 = k; } } if (rD_Q < rD_Q2) { psDelDec[num21].PartialCopyFrom(psDelDec[num22], j); array[num21 * 2] = array[num22 * 2 + 1]; } nSQ_del_dec_struct = psDelDec[num18]; if (subfr > 0 || j >= decisionDelay) { pulses[pulses_ptr + j - decisionDelay] = (sbyte)Inlines.silk_RSHIFT_ROUND(nSQ_del_dec_struct.Q_Q10[num17], 10); xq[xq_ptr + j - decisionDelay] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(Inlines.silk_SMULWW(nSQ_del_dec_struct.Xq_Q14[num17], delayedGain_Q10[num17]), 8)); sLTP_shp_Q14[sLTP_shp_buf_idx - decisionDelay] = nSQ_del_dec_struct.Shape_Q14[num17]; sLTP_Q15[sLTP_buf_idx - decisionDelay] = nSQ_del_dec_struct.Pred_Q15[num17]; } sLTP_shp_buf_idx++; sLTP_buf_idx++; for (int k = 0; k < nStatesDelayedDecision; k++) { nSQ_del_dec_struct = psDelDec[k]; int num4 = k * 2; nSQ_del_dec_struct.LF_AR_Q14 = array[num4].LF_AR_Q14; nSQ_del_dec_struct.sLPC_Q14[SilkConstants.NSQ_LPC_BUF_LENGTH + j] = array[num4].xq_Q14; nSQ_del_dec_struct.Xq_Q14[smpl_buf_idx.Val] = array[num4].xq_Q14; nSQ_del_dec_struct.Q_Q10[smpl_buf_idx.Val] = array[num4].Q_Q10; nSQ_del_dec_struct.Pred_Q15[smpl_buf_idx.Val] = Inlines.silk_LSHIFT32(array[num4].LPC_exc_Q14, 1); nSQ_del_dec_struct.Shape_Q14[smpl_buf_idx.Val] = array[num4].sLTP_shp_Q14; nSQ_del_dec_struct.Seed = Inlines.silk_ADD32_ovflw(nSQ_del_dec_struct.Seed, Inlines.silk_RSHIFT_ROUND(array[num4].Q_Q10, 10)); nSQ_del_dec_struct.RandState[smpl_buf_idx.Val] = nSQ_del_dec_struct.Seed; nSQ_del_dec_struct.RD_Q10 = array[num4].RD_Q10; } delayedGain_Q10[smpl_buf_idx.Val] = num3; } for (int k = 0; k < nStatesDelayedDecision; k++) { NSQ_del_dec_struct nSQ_del_dec_struct = psDelDec[k]; Buffer.BlockCopy(nSQ_del_dec_struct.sLPC_Q14, length * 4, nSQ_del_dec_struct.sLPC_Q14, 0, SilkConstants.NSQ_LPC_BUF_LENGTH * 4); } } private void silk_nsq_del_dec_scale_states(SilkChannelEncoder psEncC, NSQ_del_dec_struct[] psDelDec, int[] x_Q3, int x_Q3_ptr, int[] x_sc_Q10, short[] sLTP, int[] sLTP_Q15, int subfr, int nStatesDelayedDecision, int LTP_scale_Q14, int[] Gains_Q16, int[] pitchL, int signal_type, int decisionDelay) { int num = pitchL[subfr]; int num2 = Inlines.silk_INVERSE32_varQ(Inlines.silk_max(Gains_Q16[subfr], 1), 47); int num3 = ((Gains_Q16[subfr] == prev_gain_Q16) ? 65536 : Inlines.silk_DIV32_varQ(prev_gain_Q16, Gains_Q16[subfr], 16)); int b = Inlines.silk_RSHIFT_ROUND(num2, 8); for (int i = 0; i < psEncC.subfr_length; i++) { x_sc_Q10[i] = Inlines.silk_SMULWW(x_Q3[x_Q3_ptr + i], b); } prev_gain_Q16 = Gains_Q16[subfr]; if (rewhite_flag != 0) { if (subfr == 0) { num2 = Inlines.silk_LSHIFT(Inlines.silk_SMULWB(num2, LTP_scale_Q14), 2); } for (int i = sLTP_buf_idx - num - 2; i < sLTP_buf_idx; i++) { sLTP_Q15[i] = Inlines.silk_SMULWB(num2, sLTP[i]); } } if (num3 == 65536) { return; } for (int i = sLTP_shp_buf_idx - psEncC.ltp_mem_length; i < sLTP_shp_buf_idx; i++) { sLTP_shp_Q14[i] = Inlines.silk_SMULWW(num3, sLTP_shp_Q14[i]); } if (signal_type == 2 && rewhite_flag == 0) { for (int i = sLTP_buf_idx - num - 2; i < sLTP_buf_idx - decisionDelay; i++) { sLTP_Q15[i] = Inlines.silk_SMULWW(num3, sLTP_Q15[i]); } } for (int j = 0; j < nStatesDelayedDecision; j++) { NSQ_del_dec_struct nSQ_del_dec_struct = psDelDec[j]; nSQ_del_dec_struct.LF_AR_Q14 = Inlines.silk_SMULWW(num3, nSQ_del_dec_struct.LF_AR_Q14); for (int i = 0; i < SilkConstants.NSQ_LPC_BUF_LENGTH; i++) { nSQ_del_dec_struct.sLPC_Q14[i] = Inlines.silk_SMULWW(num3, nSQ_del_dec_struct.sLPC_Q14[i]); } for (int i = 0; i < psEncC.shapingLPCOrder; i++) { nSQ_del_dec_struct.sAR2_Q14[i] = Inlines.silk_SMULWW(num3, nSQ_del_dec_struct.sAR2_Q14[i]); } for (int i = 0; i < 32; i++) { nSQ_del_dec_struct.Pred_Q15[i] = Inlines.silk_SMULWW(num3, nSQ_del_dec_struct.Pred_Q15[i]); nSQ_del_dec_struct.Shape_Q14[i] = Inlines.silk_SMULWW(num3, nSQ_del_dec_struct.Shape_Q14[i]); } } } } internal class SilkPrefilterState { internal readonly short[] sLTP_shp = new short[512]; internal readonly int[] sAR_shp = new int[17]; internal int sLTP_shp_buf_idx; internal int sLF_AR_shp_Q12; internal int sLF_MA_shp_Q12; internal int sHarmHP_Q2; internal int rand_seed; internal int lagPrev; internal SilkPrefilterState() { } internal void Reset() { Arrays.MemSetShort(sLTP_shp, 0, 512); Arrays.MemSetInt(sAR_shp, 0, 17); sLTP_shp_buf_idx = 0; sLF_AR_shp_Q12 = 0; sLF_MA_shp_Q12 = 0; sHarmHP_Q2 = 0; rand_seed = 0; lagPrev = 0; } } internal class SilkResamplerState { internal readonly int[] sIIR = new int[6]; internal readonly int[] sFIR_i32 = new int[36]; internal readonly short[] sFIR_i16 = new short[36]; internal readonly short[] delayBuf = new short[48]; internal int resampler_function; internal int batchSize; internal int invRatio_Q16; internal int FIR_Order; internal int FIR_Fracs; internal int Fs_in_kHz; internal int Fs_out_kHz; internal int inputDelay; internal short[] Coefs; internal void Reset() { Arrays.MemSetInt(sIIR, 0, 6); Arrays.MemSetInt(sFIR_i32, 0, 36); Arrays.MemSetShort(sFIR_i16, 0, 36); Arrays.MemSetShort(delayBuf, 0, 48); resampler_function = 0; batchSize = 0; invRatio_Q16 = 0; FIR_Order = 0; FIR_Fracs = 0; Fs_in_kHz = 0; Fs_out_kHz = 0; inputDelay = 0; Coefs = null; } internal void Assign(SilkResamplerState other) { resampler_function = other.resampler_function; batchSize = other.batchSize; invRatio_Q16 = other.invRatio_Q16; FIR_Order = other.FIR_Order; FIR_Fracs = other.FIR_Fracs; Fs_in_kHz = other.Fs_in_kHz; Fs_out_kHz = other.Fs_out_kHz; inputDelay = other.inputDelay; Coefs = other.Coefs; Arrays.MemCopy(other.sIIR, 0, sIIR, 0, 6); Arrays.MemCopy(other.sFIR_i32, 0, sFIR_i32, 0, 36); Arrays.MemCopy(other.sFIR_i16, 0, sFIR_i16, 0, 36); Arrays.MemCopy(other.delayBuf, 0, delayBuf, 0, 48); } } internal class SilkShapeState { internal sbyte LastGainIndex; internal int HarmBoost_smth_Q16; internal int HarmShapeGain_smth_Q16; internal int Tilt_smth_Q16; internal void Reset() { LastGainIndex = 0; HarmBoost_smth_Q16 = 0; HarmShapeGain_smth_Q16 = 0; Tilt_smth_Q16 = 0; } } internal class SilkVADState { internal readonly int[] AnaState = new int[2]; internal readonly int[] AnaState1 = new int[2]; internal readonly int[] AnaState2 = new int[2]; internal readonly int[] XnrgSubfr = new int[4]; internal readonly int[] NrgRatioSmth_Q8 = new int[4]; internal short HPstate; internal readonly int[] NL = new int[4]; internal readonly int[] inv_NL = new int[4]; internal readonly int[] NoiseLevelBias = new int[4]; internal int counter; internal void Reset() { Arrays.MemSetInt(AnaState, 0, 2); Arrays.MemSetInt(AnaState1, 0, 2); Arrays.MemSetInt(AnaState2, 0, 2); Arrays.MemSetInt(XnrgSubfr, 0, 4); Arrays.MemSetInt(NrgRatioSmth_Q8, 0, 4); HPstate = 0; Arrays.MemSetInt(NL, 0, 4); Arrays.MemSetInt(inv_NL, 0, 4); Arrays.MemSetInt(NoiseLevelBias, 0, 4); counter = 0; } } internal class StereoDecodeState { internal readonly short[] pred_prev_Q13 = new short[2]; internal readonly short[] sMid = new short[2]; internal readonly short[] sSide = new short[2]; internal void Reset() { Arrays.MemSetShort(pred_prev_Q13, 0, 2); Arrays.MemSetShort(sMid, 0, 2); Arrays.MemSetShort(sSide, 0, 2); } } internal class StereoEncodeState { internal readonly short[] pred_prev_Q13 = new short[2]; internal readonly short[] sMid = new short[2]; internal readonly short[] sSide = new short[2]; internal readonly int[] mid_side_amp_Q0 = new int[4]; internal short smth_width_Q14; internal short width_prev_Q14; internal short silent_side_len; internal readonly sbyte[][][] predIx = Arrays.InitThreeDimensionalArray(3, 2, 3); internal readonly sbyte[] mid_only_flags = new sbyte[3]; internal void Reset() { Arrays.MemSetShort(pred_prev_Q13, 0, 2); Arrays.MemSetShort(sMid, 0, 2); Arrays.MemSetShort(sSide, 0, 2); Arrays.MemSetInt(mid_side_amp_Q0, 0, 4); smth_width_Q14 = 0; width_prev_Q14 = 0; silent_side_len = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { Arrays.MemSetSbyte(predIx[i][j], 0, 3); } } Arrays.MemSetSbyte(mid_only_flags, 0, 3); } } internal class TOCStruct { internal int VADFlag; internal readonly int[] VADFlags = new int[3]; internal int inbandFECFlag; internal void Reset() { VADFlag = 0; Arrays.MemSetInt(VADFlags, 0, 3); inbandFECFlag = 0; } } } namespace Concentus.Silk.Enums { internal static class DecoderAPIFlag { internal const int FLAG_DECODE_NORMAL = 0; internal const int FLAG_PACKET_LOST = 1; internal const int FLAG_DECODE_LBRR = 2; } internal static class SilkError { internal static int SILK_NO_ERROR = 0; internal static int SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES = -101; internal static int SILK_ENC_FS_NOT_SUPPORTED = -102; internal static int SILK_ENC_PACKET_SIZE_NOT_SUPPORTED = -103; internal static int SILK_ENC_PAYLOAD_BUF_TOO_SHORT = -104; internal static int SILK_ENC_INVALID_LOSS_RATE = -105; internal static int SILK_ENC_INVALID_COMPLEXITY_SETTING = -106; internal static int SILK_ENC_INVALID_INBAND_FEC_SETTING = -107; internal static int SILK_ENC_INVALID_DTX_SETTING = -108; internal static int SILK_ENC_INVALID_CBR_SETTING = -109; internal static int SILK_ENC_INTERNAL_ERROR = -110; internal static int SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR = -111; internal static int SILK_DEC_INVALID_SAMPLING_FREQUENCY = -200; internal static int SILK_DEC_PAYLOAD_TOO_LARGE = -201; internal static int SILK_DEC_PAYLOAD_ERROR = -202; internal static int SILK_DEC_INVALID_FRAME_SIZE = -203; } } namespace Concentus.Structs { internal class ChannelLayout { internal int nb_channels; internal int nb_streams; internal int nb_coupled_streams; internal readonly byte[] mapping = new byte[256]; internal void Reset() { nb_channels = 0; nb_streams = 0; nb_coupled_streams = 0; MemoryExtensions.AsSpan(mapping).Clear(); } } internal class MLP { internal int layers; internal int[] topo; internal float[] weights; } internal class OpusDecoder : IOpusDecoder, IDisposable { internal int channels; internal int Fs; internal readonly DecControlState DecControl = new DecControlState(); internal int decode_gain; internal int stream_channels; internal OpusBandwidth bandwidth; internal OpusMode mode; internal OpusMode prev_mode; internal int frame_size; internal int prev_redundancy; internal int last_packet_duration; internal uint rangeFinal; internal SilkDecoder SilkDecoder = new SilkDecoder(); internal CeltDecoder Celt_Decoder = new CeltDecoder(); private static readonly byte[] SILENCE = new byte[2] { 255, 255 }; public OpusBandwidth Bandwidth => bandwidth; public uint FinalRange => rangeFinal; public int SampleRate => Fs; public int NumChannels => channels; public int Pitch { get { if (prev_mode == OpusMode.MODE_CELT_ONLY) { return Celt_Decoder.GetPitch(); } return DecControl.prevPitchLag; } } public int Gain { get { return decode_gain; } set { if (value < -32768 || value > 32767) { throw new ArgumentException("Gain must be within the range of a signed int16"); } decode_gain = value; } } public int LastPacketDuration => last_packet_duration; internal OpusDecoder() { } internal void Reset() { channels = 0; Fs = 0; DecControl.Reset(); decode_gain = 0; PartialReset(); } internal void PartialReset() { stream_channels = 0; bandwidth = (OpusBandwidth)0; mode = (OpusMode)0; prev_mode = (OpusMode)0; frame_size = 0; prev_redundancy = 0; last_packet_duration = 0; rangeFinal = 0u; } [Obsolete("Use OpusCodecFactory methods which can give you native code if supported by your platform")] public OpusDecoder(int Fs, int channels) { if (Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000) { throw new ArgumentException("Sample rate is invalid (must be 8/12/16/24/48 Khz)"); } if (channels != 1 && channels != 2) { throw new ArgumentException("Number of channels must be 1 or 2"); } int num = opus_decoder_init(Fs, channels); switch (num) { case -1: throw new ArgumentException("OPUS_BAD_ARG when creating decoder"); default: throw new OpusException("Error while initializing decoder: " + CodecHelpers.opus_strerror(num), num); case 0: break; } } internal int opus_decoder_init(int Fs, int channels) { if ((Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000) || (channels != 1 && channels != 2)) { return -1; } Reset(); SilkDecoder silkDecoder = SilkDecoder; CeltDecoder celt_Decoder = Celt_Decoder; stream_channels = (this.channels = channels); this.Fs = Fs; DecControl.API_sampleRate = this.Fs; DecControl.nChannelsAPI = this.channels; if (DecodeAPI.silk_InitDecoder(silkDecoder) != 0) { return -3; } if (celt_Decoder.celt_decoder_init(Fs, channels) != 0) { return -3; } celt_Decoder.SetSignalling(0); prev_mode = (OpusMode)0; frame_size = Fs / 400; return 0; } internal int opus_decode_frame(ReadOnlySpan data, int data_ptr, int len, Span pcm, int pcm_ptr, int frame_size, int decode_fec) { int num = 0; EntropyCoder entropyCoder = new EntropyCoder(); short[] array = null; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; uint num6 = 0u; SilkDecoder silkDecoder = SilkDecoder; CeltDecoder celt_Decoder = Celt_Decoder; int num7 = Fs / 50; int num8 = num7 >> 1; int num9 = num8 >> 1; int num10 = num9 >> 1; if (frame_size < num10) { return -2; } frame_size = Inlines.IMIN(frame_size, Fs / 25 * 3); if (len <= 1) { data = null; frame_size = Inlines.IMIN(frame_size, this.frame_size); } int num11; OpusMode opusMode; if (!data.IsEmpty) { num11 = this.frame_size; opusMode = mode; entropyCoder.dec_init(data.Slice(data_ptr), (uint)len); } else { num11 = frame_size; opusMode = prev_mode; if (opusMode == (OpusMode)0) { for (int i = pcm_ptr; i < pcm_ptr + num11 * channels; i++) { pcm[i] = 0; } return num11; } if (num11 > num7) { do { int num12 = opus_decode_frame(null, 0, 0, pcm, pcm_ptr, Inlines.IMIN(num11, num7), 0); if (num12 < 0) { return num12; } pcm_ptr += num12 * channels; num11 -= num12; } while (num11 > 0); return frame_size; } if (num11 < num7) { if (num11 > num8) { num11 = num8; } else if (opusMode != OpusMode.MODE_SILK_ONLY && num11 > num9 && num11 < num8) { num11 = num9; } } } int num13 = ((opusMode != OpusMode.MODE_CELT_ONLY && frame_size >= num8) ? 1 : 0); int num14 = 0; int num15 = 0; if (!data.IsEmpty && prev_mode > (OpusMode)0 && ((opusMode == OpusMode.MODE_CELT_ONLY && prev_mode != OpusMode.MODE_CELT_ONLY && prev_redundancy == 0) || (opusMode != OpusMode.MODE_CELT_ONLY && prev_mode == OpusMode.MODE_CELT_ONLY))) { num2 = 1; if (opusMode == OpusMode.MODE_CELT_ONLY) { num15 = num9 * channels; } else { num14 = num9 * channels; } } short[] array2 = new short[num15]; if (num2 != 0 && opusMode == OpusMode.MODE_CELT_ONLY) { array = array2; opus_decode_frame(null, 0, 0, array, 0, Inlines.IMIN(num9, num11), 0); } if (num11 > frame_size) { return -1; } frame_size = num11; short[] array3 = new short[(opusMode != OpusMode.MODE_CELT_ONLY && num13 == 0) ? (Inlines.IMAX(num8, frame_size) * channels) : 0]; if (opusMode != OpusMode.MODE_CELT_ONLY) { int num16 = 0; Span span; if (num13 != 0) { span = pcm; num16 = pcm_ptr; } else { span = array3; num16 = 0; } if (prev_mode == OpusMode.MODE_CELT_ONLY) { DecodeAPI.silk_InitDecoder(silkDecoder); } DecControl.payloadSize_ms = Inlines.IMAX(10, 1000 * num11 / Fs); if (!data.IsEmpty) { DecControl.nChannelsInternal = stream_channels; if (opusMode == OpusMode.MODE_SILK_ONLY) { if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) { DecControl.internalSampleRate = 8000; } else if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { DecControl.internalSampleRate = 12000; } else if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { DecControl.internalSampleRate = 16000; } else { DecControl.internalSampleRate = 16000; } } else { DecControl.internalSampleRate = 16000; } } int num17 = (data.IsEmpty ? 1 : (2 * decode_fec)); int num18 = 0; do { int newPacketFlag = ((num18 == 0) ? 1 : 0); if (DecodeAPI.silk_Decode(silkDecoder, DecControl, data.Slice(data_ptr), num17, newPacketFlag, entropyCoder, span, num16, out var nSamplesOut) != 0) { if (num17 == 0) { return -3; } nSamplesOut = frame_size; Arrays.MemSetWithOffset(span, 0, num16, frame_size * channels); } num16 += nSamplesOut * channels; num18 += nSamplesOut; } while (num18 < frame_size); } int startBand = 0; if (decode_fec == 0 && opusMode != OpusMode.MODE_CELT_ONLY && !data.IsEmpty && entropyCoder.tell() + 17 + 20 * ((mode == OpusMode.MODE_HYBRID) ? 1 : 0) <= 8 * len) { num3 = ((opusMode != OpusMode.MODE_HYBRID) ? 1 : entropyCoder.dec_bit_logp(data.Slice(data_ptr), 12u)); if (num3 != 0) { num5 = entropyCoder.dec_bit_logp(data.Slice(data_ptr), 1u); num4 = ((opusMode == OpusMode.MODE_HYBRID) ? ((int)(entropyCoder.dec_uint(data.Slice(data_ptr), 256u) + 2)) : (len - (entropyCoder.tell() + 7 >> 3))); len -= num4; if (len * 8 < entropyCoder.tell()) { len = 0; num4 = 0; num3 = 0; } entropyCoder.storage = (uint)(entropyCoder.storage - num4); } } if (opusMode != OpusMode.MODE_CELT_ONLY) { startBand = 17; } int endBand = 21; switch (bandwidth) { case OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND: endBand = 13; break; case OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND: case OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND: endBand = 17; break; case OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND: endBand = 19; break; case OpusBandwidth.OPUS_BANDWIDTH_FULLBAND: endBand = 21; break; } celt_Decoder.SetEndBand(endBand); celt_Decoder.SetChannels(stream_channels); if (num3 != 0) { num2 = 0; num14 = 0; } short[] array4 = new short[num14]; if (num2 != 0 && opusMode != OpusMode.MODE_CELT_ONLY) { array = array4; opus_decode_frame(null, 0, 0, array, 0, Inlines.IMIN(num9, num11), 0); } short[] array5 = new short[(num3 != 0) ? (num9 * channels) : 0]; if (num3 != 0 && num5 != 0) { celt_Decoder.SetStartBand(0); celt_Decoder.celt_decode_with_ec(data, data_ptr + len, num4, array5, 0, num9, null, 0); num6 = celt_Decoder.GetFinalRange(); } celt_Decoder.SetStartBand(startBand); if (opusMode != OpusMode.MODE_SILK_ONLY) { int num19 = Inlines.IMIN(num7, frame_size); if (opusMode != prev_mode && prev_mode > (OpusMode)0 && prev_redundancy == 0) { celt_Decoder.ResetState(); } num = celt_Decoder.celt_decode_with_ec((decode_fec != 0) ? ((ReadOnlySpan)null) : data, data_ptr, len, pcm, pcm_ptr, num19, entropyCoder, num13); } else { if (num13 == 0) { for (int i = pcm_ptr; i < frame_size * channels + pcm_ptr; i++) { pcm[i] = 0; } } if (prev_mode == OpusMode.MODE_HYBRID && (num3 == 0 || num5 == 0 || prev_redundancy == 0)) { celt_Decoder.SetStartBand(0); celt_Decoder.celt_decode_with_ec(SILENCE, 0, 2, pcm, pcm_ptr, num10, null, num13); } } if (opusMode != OpusMode.MODE_CELT_ONLY && num13 == 0) { for (int i = 0; i < frame_size * channels; i++) { pcm[pcm_ptr + i] = Inlines.SAT16(Inlines.ADD32(pcm[pcm_ptr + i], array3[i])); } } int[] window = celt_Decoder.GetMode().window; if (num3 != 0 && num5 == 0) { celt_Decoder.ResetState(); celt_Decoder.SetStartBand(0); celt_Decoder.celt_decode_with_ec(data, data_ptr + len, num4, array5, 0, num9, null, 0); num6 = celt_Decoder.GetFinalRange(); CodecHelpers.smooth_fade(pcm, pcm_ptr + channels * (frame_size - num10), array5, channels * num10, pcm, pcm_ptr + channels * (frame_size - num10), num10, channels, window, Fs); } if (num3 != 0 && num5 != 0) { for (int j = 0; j < channels; j++) { for (int i = 0; i < num10; i++) { pcm[channels * i + j + pcm_ptr] = array5[channels * i + j]; } } CodecHelpers.smooth_fade(array5, channels * num10, pcm, pcm_ptr + channels * num10, pcm, pcm_ptr + channels * num10, num10, channels, window, Fs); } if (num2 != 0) { if (num11 >= num9) { for (int i = 0; i < channels * num10; i++) { pcm[i] = array[i]; } CodecHelpers.smooth_fade(array, channels * num10, pcm, pcm_ptr + channels * num10, pcm, pcm_ptr + channels * num10, num10, channels, window, Fs); } else { CodecHelpers.smooth_fade(array, 0, pcm, pcm_ptr, pcm, pcm_ptr, num10, channels, window, Fs); } } if (decode_gain != 0) { int b = Inlines.celt_exp2(Inlines.MULT16_16_P15(21771, decode_gain)); for (int i = pcm_ptr; i < pcm_ptr + frame_size * channels; i++) { int x = Inlines.MULT16_32_P16(pcm[i], b); pcm[i] = (short)Inlines.SATURATE(x, 32767); } } if (len <= 1) { rangeFinal = 0u; } else { rangeFinal = entropyCoder.rng ^ num6; } prev_mode = opusMode; prev_redundancy = ((num3 != 0 && num5 == 0) ? 1 : 0); if (num >= 0) { return num11; } return num; } internal int opus_decode_native(ReadOnlySpan data, int data_ptr, int len, Span pcm_out, int pcm_out_ptr, int frame_size, int decode_fec, int self_delimited, out int packet_offset, int soft_clip) { packet_offset = 0; short[] array = new short[48]; if (decode_fec < 0 || decode_fec > 1) { return -1; } if ((decode_fec != 0 || len == 0 || data.IsEmpty) && frame_size % (Fs / 400) != 0) { return -1; } if (len == 0 || data.IsEmpty) { int num = 0; do { int num2 = opus_decode_frame(null, 0, 0, pcm_out, pcm_out_ptr + num * channels, frame_size - num, 0); if (num2 < 0) { return num2; } num += num2; } while (num < frame_size); last_packet_duration = num; return num; } if (len < 0) { return -1; } OpusMode encoderMode = OpusPacketInfo.GetEncoderMode(data.Slice(data_ptr)); OpusBandwidth opusBandwidth = OpusPacketInfo.GetBandwidth(data.Slice(data_ptr)); int numSamplesPerFrame = OpusPacketInfo.GetNumSamplesPerFrame(data.Slice(data_ptr), Fs); int numEncodedChannels = OpusPacketInfo.GetNumEncodedChannels(data.Slice(data_ptr)); byte out_toc; int payload_offset; int num3 = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, self_delimited, out out_toc, null, null, 0, array, 0, out payload_offset, out packet_offset); if (num3 < 0) { return num3; } data_ptr += payload_offset; if (decode_fec != 0) { int packet_offset2; if (frame_size < numSamplesPerFrame || encoderMode == OpusMode.MODE_CELT_ONLY || mode == OpusMode.MODE_CELT_ONLY) { return opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size, 0, 0, out packet_offset2, soft_clip); } int num4 = last_packet_duration; int num5; if (frame_size - numSamplesPerFrame != 0) { num5 = opus_decode_native(null, 0, 0, pcm_out, pcm_out_ptr, frame_size - numSamplesPerFrame, 0, 0, out packet_offset2, soft_clip); if (num5 < 0) { last_packet_duration = num4; return num5; } } mode = encoderMode; bandwidth = opusBandwidth; this.frame_size = numSamplesPerFrame; stream_channels = numEncodedChannels; num5 = opus_decode_frame(data, data_ptr, array[0], pcm_out, pcm_out_ptr + channels * (frame_size - numSamplesPerFrame), numSamplesPerFrame, 1); if (num5 < 0) { return num5; } last_packet_duration = frame_size; return frame_size; } if (num3 * numSamplesPerFrame > frame_size) { return -2; } mode = encoderMode; bandwidth = opusBandwidth; this.frame_size = numSamplesPerFrame; stream_channels = numEncodedChannels; int num6 = 0; for (int i = 0; i < num3; i++) { int num7 = opus_decode_frame(data, data_ptr, array[i], pcm_out, pcm_out_ptr + num6 * channels, frame_size - num6, 0); if (num7 < 0) { return num7; } data_ptr += array[i]; num6 += num7; } last_packet_duration = num6; return num6; } [Obsolete("Use Span<> overrides if possible")] public int Decode(byte[] in_data, int in_data_offset, int len, short[] out_pcm, int out_pcm_offset, int frame_size, bool decode_fec = false) { if (in_data == null) { return Decode(ReadOnlySpan.Empty, MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } return Decode(MemoryExtensions.AsSpan(in_data, in_data_offset, len), MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } public int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false) { if (frame_size <= 0) { throw new ArgumentException("Frame size must be > 0"); } try { int packet_offset; int num = opus_decode_native(in_data, 0, in_data.Length, out_pcm, 0, frame_size, decode_fec ? 1 : 0, 0, out packet_offset, 0); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG while decoding"); } throw new OpusException("An error occurred during decoding: " + CodecHelpers.opus_strerror(num), num); } return num; } catch (ArgumentException ex) { throw new OpusException("public error during decoding: " + ex.Message, -1); } } [Obsolete("Use Span<> overrides if possible")] public int Decode(byte[] in_data, int in_data_offset, int len, float[] out_pcm, int out_pcm_offset, int frame_size, bool decode_fec = false) { if (in_data == null) { return Decode(ReadOnlySpan.Empty, MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } return Decode(MemoryExtensions.AsSpan(in_data, in_data_offset, len), MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } public int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false) { if (frame_size <= 0) { throw new ArgumentException("Frame size must be > 0"); } if (!in_data.IsEmpty && in_data.Length > 0 && !decode_fec) { int numSamples = OpusPacketInfo.GetNumSamples(in_data, Fs); if (numSamples <= 0) { throw new OpusException("An invalid packet was provided (unable to parse # of samples)", -4); } frame_size = Inlines.IMIN(frame_size, numSamples); } short[] array = new short[frame_size * channels]; try { int packet_offset; int num = opus_decode_native(in_data, 0, in_data.Length, array, 0, frame_size, decode_fec ? 1 : 0, 0, out packet_offset, 0); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG when decoding"); } throw new OpusException("An error occurred during decoding: " + CodecHelpers.opus_strerror(num), num); } if (num > 0) { for (int i = 0; i < num * channels; i++) { out_pcm[i] = 3.0517578E-05f * (float)array[i]; } } return num; } catch (ArgumentException ex) { throw new OpusException("public error during decoding: " + ex.Message, -1); } } public void ResetState() { PartialReset(); Celt_Decoder.ResetState(); DecodeAPI.silk_InitDecoder(SilkDecoder); stream_channels = channels; frame_size = Fs / 400; } public string GetVersionString() { return CodecHelpers.GetVersionString(); } public void Dispose() { } } internal class OpusEncoder : IOpusEncoder, IDisposable { internal readonly EncControlState silk_mode = new EncControlState(); internal OpusApplication application; internal int channels; internal int delay_compensation; internal int force_channels; internal OpusSignal signal_type; internal OpusBandwidth user_bandwidth; internal OpusBandwidth max_bandwidth; internal OpusMode user_forced_mode; internal int voice_ratio; internal int Fs; internal int use_vbr; internal int vbr_constraint; internal OpusFramesize variable_duration; internal int bitrate_bps; internal int user_bitrate_bps; internal int lsb_depth; internal int encoder_buffer; internal int lfe; internal readonly TonalityAnalysisState analysis = new TonalityAnalysisState(); internal int stream_channels; internal short hybrid_stereo_width_Q14; internal int variable_HP_smth2_Q15; internal int prev_HB_gain; internal readonly int[] hp_mem = new int[4]; internal OpusMode mode; internal OpusMode prev_mode; internal int prev_channels; internal int prev_framesize; internal OpusBandwidth bandwidth; internal int silk_bw_switch; internal int first; internal int[] energy_masking; internal readonly StereoWidthState width_mem = new StereoWidthState(); internal readonly short[] delay_buffer = new short[960]; internal OpusBandwidth detected_bandwidth; internal uint rangeFinal; private int? _vqLevel; internal readonly SilkEncoder SilkEncoder = new SilkEncoder(); internal readonly CeltEncoder Celt_Encoder = new CeltEncoder(); private static readonly int[][] vqTable = new int[11][] { new int[2] { 7000, 16000 }, new int[2] { 10000, 24000 }, new int[2] { 13000, 32000 }, new int[2] { 17000, 48000 }, new int[2] { 20000, 64000 }, new int[2] { 24000, 80000 }, new int[2] { 28000, 96000 }, new int[2] { 32000, 112000 }, new int[2] { 38000, 128000 }, new int[2] { 48000, 192000 }, new int[2] { 64000, 256000 } }; public OpusApplication Application { get { return application; } set { if (first == 0 && application != value) { throw new ArgumentException("Application cannot be changed after encoding has started"); } application = value; } } public int Bitrate { get { return user_bitrate_to_bitrate(user_bitrate_bps, prev_framesize, 1276); } set { if (ConstantQuality.HasValue) { throw new ArgumentException("Bitrate is read-only while the ConstantQuality parameter is set"); } if (value != -1000 && value != -1) { if (value <= 0) { throw new ArgumentException("Bitrate must be positive"); } if (value <= 500) { value = 500; } else if (value > 300000 * channels) { value = 300000 * channels; } } user_bitrate_bps = value; } } public int ForceChannels { get { return force_channels; } set { if ((value < 1 || value > channels) && value != -1000) { throw new ArgumentException("Force channels must be <= num. of channels"); } force_channels = value; } } public OpusBandwidth MaxBandwidth { get { return max_bandwidth; } set { max_bandwidth = value; if (max_bandwidth == OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) { silk_mode.maxInternalSampleRate = 8000; } else if (max_bandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { silk_mode.maxInternalSampleRate = 12000; } else { silk_mode.maxInternalSampleRate = 16000; } } } public OpusBandwidth Bandwidth { get { return bandwidth; } set { user_bandwidth = value; if (user_bandwidth == OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) { silk_mode.maxInternalSampleRate = 8000; } else if (user_bandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { silk_mode.maxInternalSampleRate = 12000; } else { silk_mode.maxInternalSampleRate = 16000; } } } public bool UseDTX { get { return silk_mode.useDTX != 0; } set { silk_mode.useDTX = (value ? 1 : 0); } } public int Complexity { get { return silk_mode.complexity; } set { if (value < 0 || value > 10) { throw new ArgumentException("Complexity must be between 0 and 10"); } silk_mode.complexity = value; Celt_Encoder.SetComplexity(value); } } public bool UseInbandFEC { get { return silk_mode.useInBandFEC != 0; } set { silk_mode.useInBandFEC = (value ? 1 : 0); } } public int PacketLossPercent { get { return silk_mode.packetLossPercentage; } set { if (value < 0 || value > 100) { throw new ArgumentException("Packet loss must be between 0 and 100"); } silk_mode.packetLossPercentage = value; Celt_Encoder.SetPacketLossPercent(value); } } public bool UseVBR { get { return use_vbr != 0; } set { use_vbr = (value ? 1 : 0); silk_mode.useCBR = ((!value) ? 1 : 0); } } public bool UseConstrainedVBR { get { return vbr_constraint != 0; } set { vbr_constraint = (value ? 1 : 0); } } public OpusSignal SignalType { get { return signal_type; } set { signal_type = value; } } public int Lookahead { get { int num = Fs / 400; if (application != OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY) { num += delay_compensation; } return num; } } public int SampleRate => Fs; public int NumChannels => channels; public uint FinalRange => rangeFinal; public int LSBDepth { get { return lsb_depth; } set { if (value < 8 || value > 24) { throw new ArgumentException("LSB depth must be between 8 and 24"); } lsb_depth = value; } } public OpusFramesize ExpertFrameDuration { get { return variable_duration; } set { variable_duration = value; Celt_Encoder.SetExpertFrameDuration(value); } } public OpusMode ForceMode { get { return user_forced_mode; } set { user_forced_mode = value; } } public bool IsLFE { get { return lfe != 0; } set { lfe = (value ? 1 : 0); Celt_Encoder.SetLFE(value ? 1 : 0); } } public bool PredictionDisabled { get { return silk_mode.reducedDependency != 0; } set { silk_mode.reducedDependency = (value ? 1 : 0); } } public bool EnableAnalysis { get { return analysis.enabled; } set { if (!value && _vqLevel.HasValue) { throw new ArgumentException("You cannot disable analysis while also specifying a ConstantQuality parameter"); } if (value && Fs != 48000) { throw new ArgumentException("EnableAnalysis only works if the encoder is in 48000Khz mode"); } analysis.enabled = value; } } public int? ConstantQuality { get { return _vqLevel; } set { if (value.HasValue && (value.Value < 0 || value.Value > 10)) { throw new ArgumentException("Constant quality VBR level must be either null (disabled) or between 0 and 10, inclusive."); } if (value.HasValue && Fs != 48000) { throw new ArgumentException("ConstantQuality only works if the encoder is in 48000Khz mode"); } EnableAnalysis = true; _vqLevel = value; } } public float MusicProbability => analysis.music_prob; internal OpusEncoder() { } internal void Reset() { silk_mode.Reset(); application = OpusApplication.OPUS_APPLICATION_UNIMPLEMENTED; channels = 0; delay_compensation = 0; force_channels = 0; signal_type = (OpusSignal)0; user_bandwidth = (OpusBandwidth)0; max_bandwidth = (OpusBandwidth)0; user_forced_mode = (OpusMode)0; voice_ratio = 0; Fs = 0; use_vbr = 0; vbr_constraint = 0; variable_duration = (OpusFramesize)0; bitrate_bps = 0; user_bitrate_bps = 0; lsb_depth = 0; encoder_buffer = 0; lfe = 0; analysis.Reset(); PartialReset(); } internal void PartialReset() { stream_channels = 0; hybrid_stereo_width_Q14 = 0; variable_HP_smth2_Q15 = 0; prev_HB_gain = 0; Arrays.MemSetInt(hp_mem, 0, 4); mode = (OpusMode)0; prev_mode = (OpusMode)0; prev_channels = 0; prev_framesize = 0; bandwidth = (OpusBandwidth)0; silk_bw_switch = 0; first = 0; energy_masking = null; width_mem.Reset(); Arrays.MemSetShort(delay_buffer, 0, 960); detected_bandwidth = (OpusBandwidth)0; rangeFinal = 0u; } public void ResetState() { EncControlState encStatus = new EncControlState(); analysis.Reset(); PartialReset(); Celt_Encoder.ResetState(); EncodeAPI.silk_InitEncoder(SilkEncoder, encStatus); stream_channels = channels; hybrid_stereo_width_Q14 = 16384; prev_HB_gain = 32767; first = 1; mode = OpusMode.MODE_HYBRID; bandwidth = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; variable_HP_smth2_Q15 = Inlines.silk_LSHIFT(Inlines.silk_lin2log(60), 8); } [Obsolete("Use OpusCodecFactory methods which can give you native code if supported by your platform")] public OpusEncoder(int Fs, int channels, OpusApplication application) { if (Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000) { throw new ArgumentException("Sample rate is invalid (must be 8/12/16/24/48 Khz)"); } if (channels != 1 && channels != 2) { throw new ArgumentException("Number of channels must be 1 or 2"); } int num = opus_init_encoder(Fs, channels, application); switch (num) { case -1: throw new ArgumentException("OPUS_BAD_ARG when creating encoder"); default: throw new OpusException("Error while initializing encoder: " + CodecHelpers.opus_strerror(num), num); case 0: break; } } internal int opus_init_encoder(int Fs, int channels, OpusApplication application) { if ((Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000) || (channels != 1 && channels != 2) || application == OpusApplication.OPUS_APPLICATION_UNIMPLEMENTED) { return -1; } Reset(); SilkEncoder silkEncoder = SilkEncoder; CeltEncoder celt_Encoder = Celt_Encoder; stream_channels = (this.channels = channels); this.Fs = Fs; if (EncodeAPI.silk_InitEncoder(silkEncoder, silk_mode) != 0) { return -3; } silk_mode.nChannelsAPI = channels; silk_mode.nChannelsInternal = channels; silk_mode.API_sampleRate = this.Fs; silk_mode.maxInternalSampleRate = 16000; silk_mode.minInternalSampleRate = 8000; silk_mode.desiredInternalSampleRate = 16000; silk_mode.payloadSize_ms = 20; silk_mode.bitRate = 25000; silk_mode.packetLossPercentage = 0; silk_mode.complexity = 9; silk_mode.useInBandFEC = 0; silk_mode.useDTX = 0; silk_mode.useCBR = 0; silk_mode.reducedDependency = 0; if (celt_Encoder.celt_encoder_init(Fs, channels) != 0) { return -3; } celt_Encoder.SetSignalling(0); celt_Encoder.SetComplexity(silk_mode.complexity); use_vbr = 1; vbr_constraint = 1; user_bitrate_bps = -1000; bitrate_bps = 3000 + Fs * channels; this.application = application; signal_type = OpusSignal.OPUS_SIGNAL_AUTO; user_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_AUTO; max_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; force_channels = -1000; user_forced_mode = OpusMode.MODE_AUTO; voice_ratio = -1; encoder_buffer = this.Fs / 100; lsb_depth = 24; variable_duration = OpusFramesize.OPUS_FRAMESIZE_ARG; delay_compensation = this.Fs / 250; hybrid_stereo_width_Q14 = 16384; prev_HB_gain = 32767; variable_HP_smth2_Q15 = Inlines.silk_LSHIFT(Inlines.silk_lin2log(60), 8); first = 1; mode = OpusMode.MODE_HYBRID; bandwidth = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; Analysis.tonality_analysis_init(analysis); return 0; } internal int user_bitrate_to_bitrate(int user_bitrate, int frame_size, int max_data_bytes) { if (frame_size == 0) { frame_size = Fs / 400; } return user_bitrate switch { -1000 => 60 * Fs / frame_size + Fs * channels, -1 => max_data_bytes * 8 * Fs / frame_size, _ => user_bitrate, }; } internal int opus_encode_native(ReadOnlySpan pcm, int pcm_ptr, int frame_size, Span data, int data_ptr, int out_data_bytes, int lsb_depth, ReadOnlySpan analysis_pcm, int analysis_size, int c1, int c2, int analysis_channels, Downmix.downmix_func downmix, int float_api) { int num = 0; EntropyCoder entropyCoder = new EntropyCoder(); int num2 = 0; int startBand = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; uint num7 = 0u; AnalysisInfo analysisInfo = new AnalysisInfo(); int num8 = -1; int read_subframe = -1; int num9 = Inlines.IMIN(1276, out_data_bytes); rangeFinal = 0u; if ((variable_duration == (OpusFramesize)0 && 400 * frame_size != Fs && 200 * frame_size != Fs && 100 * frame_size != Fs && 50 * frame_size != Fs && 25 * frame_size != Fs && 50 * frame_size != 3 * Fs) || 400 * frame_size < Fs || num9 <= 0) { return -1; } SilkEncoder silkEncoder = SilkEncoder; CeltEncoder celt_Encoder = Celt_Encoder; int num10 = ((application != OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY) ? delay_compensation : 0); lsb_depth = Inlines.IMIN(lsb_depth, this.lsb_depth); CeltMode celtMode = celt_Encoder.GetMode(); voice_ratio = -1; if (analysis.enabled) { analysisInfo.valid = 0; if ((_vqLevel.HasValue || silk_mode.complexity >= 7) && Fs == 48000) { num8 = analysis.read_pos; read_subframe = analysis.read_subframe; Analysis.run_analysis(analysis, celtMode, analysis_pcm, analysis_size, frame_size, c1, c2, analysis_channels, Fs, lsb_depth, downmix, analysisInfo); } detected_bandwidth = (OpusBandwidth)0; if (analysisInfo.valid != 0) { if (signal_type == OpusSignal.OPUS_SIGNAL_AUTO) { voice_ratio = (int)Math.Floor(0.5f + 100f * (1f - analysisInfo.music_prob)); } int num11 = analysisInfo.bandwidth; if (num11 <= 12) { detected_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } else if (num11 <= 14) { detected_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND; } else if (num11 <= 16) { detected_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } else if (num11 <= 18) { detected_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND; } else { detected_bandwidth = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; } if (_vqLevel.HasValue) { user_bitrate_bps = GetVariableQualityBitrate(_vqLevel.Value, analysis.music_prob); } } } int num12 = ((channels == 2 && force_channels != 1) ? CodecHelpers.compute_stereo_width(pcm, pcm_ptr, frame_size, Fs, width_mem) : 0); int num13 = num10; bitrate_bps = user_bitrate_to_bitrate(user_bitrate_bps, frame_size, num9); int num14 = Fs / frame_size; if (use_vbr == 0) { int num15 = 3 * Fs / frame_size; int num16 = Inlines.IMIN((3 * bitrate_bps / 8 + num15 / 2) / num15, num9); bitrate_bps = num16 * num15 * 8 / 3; num9 = num16; } if (num9 < 3 || bitrate_bps < 3 * num14 * 8 || (num14 < 50 && (num9 * num14 < 300 || bitrate_bps < 2400))) { OpusMode opusMode = mode; OpusBandwidth opusBandwidth = ((bandwidth == (OpusBandwidth)0) ? OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND : bandwidth); if (opusMode == (OpusMode)0) { opusMode = OpusMode.MODE_SILK_ONLY; } if (num14 > 100) { opusMode = OpusMode.MODE_CELT_ONLY; } if (num14 < 50) { opusMode = OpusMode.MODE_SILK_ONLY; } if (opusMode == OpusMode.MODE_SILK_ONLY && opusBandwidth > OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { opusBandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } else if (opusMode == OpusMode.MODE_CELT_ONLY && opusBandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { opusBandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } else if (opusMode == OpusMode.MODE_HYBRID && opusBandwidth <= OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) { opusBandwidth = OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND; } data[data_ptr] = CodecHelpers.gen_toc(opusMode, num14, opusBandwidth, stream_channels); num = 1; if (use_vbr == 0) { num = OpusRepacketizer.PadPacket(data, data_ptr, num, num9); if (num == 0) { num = num9; } } return num; } int num17 = num14 * num9 * 8; int num18 = bitrate_bps - (40 * channels + 20) * (Fs / frame_size - 50); int num19; if (signal_type == OpusSignal.OPUS_SIGNAL_VOICE) { num19 = 127; } else if (signal_type == OpusSignal.OPUS_SIGNAL_MUSIC) { num19 = 0; } else if (voice_ratio < 0) { num19 = ((application != OpusApplication.OPUS_APPLICATION_VOIP) ? 48 : 115); } else { num19 = voice_ratio * 327 >> 8; if (application == OpusApplication.OPUS_APPLICATION_AUDIO) { num19 = Inlines.IMIN(num19, 115); } } if (force_channels != -1000 && channels == 2) { stream_channels = force_channels; } else if (channels == 2) { int num20 = 30000 + (0 >> 14); num20 = ((stream_channels != 2) ? (num20 + 1000) : (num20 - 1000)); stream_channels = ((num18 <= num20) ? 1 : 2); } else { stream_channels = channels; } num18 = bitrate_bps - (40 * stream_channels + 20) * (Fs / frame_size - 50); if (application == OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY) { mode = OpusMode.MODE_CELT_ONLY; } else if (user_forced_mode == OpusMode.MODE_AUTO) { int num21 = Inlines.MULT16_32_Q15(32767 - num12, Tables.mode_thresholds[0][0]) + Inlines.MULT16_32_Q15(num12, Tables.mode_thresholds[1][0]); int num22 = Inlines.MULT16_32_Q15(32767 - num12, Tables.mode_thresholds[1][1]) + Inlines.MULT16_32_Q15(num12, Tables.mode_thresholds[1][1]); int num23 = num22 + (num19 * num19 * (num21 - num22) >> 14); if (application == OpusApplication.OPUS_APPLICATION_VOIP) { num23 += 8000; } if (prev_mode == OpusMode.MODE_CELT_ONLY) { num23 -= 4000; } else if (prev_mode > (OpusMode)0) { num23 += 4000; } mode = ((num18 >= num23) ? OpusMode.MODE_CELT_ONLY : OpusMode.MODE_SILK_ONLY); if (silk_mode.useInBandFEC != 0 && silk_mode.packetLossPercentage > 128 - num19 >> 4) { mode = OpusMode.MODE_SILK_ONLY; } if (silk_mode.useDTX != 0 && num19 > 100) { mode = OpusMode.MODE_SILK_ONLY; } } else { mode = user_forced_mode; } if (mode != OpusMode.MODE_CELT_ONLY && frame_size < Fs / 100) { mode = OpusMode.MODE_CELT_ONLY; } if (lfe != 0) { mode = OpusMode.MODE_CELT_ONLY; } if (num9 < ((num14 > 50) ? 12000 : 8000) * frame_size / (Fs * 8)) { mode = OpusMode.MODE_CELT_ONLY; } if (stream_channels == 1 && prev_channels == 2 && silk_mode.toMono == 0 && mode != OpusMode.MODE_CELT_ONLY && prev_mode != OpusMode.MODE_CELT_ONLY) { silk_mode.toMono = 1; stream_channels = 2; } else { silk_mode.toMono = 0; } if (prev_mode > (OpusMode)0 && ((mode != OpusMode.MODE_CELT_ONLY && prev_mode == OpusMode.MODE_CELT_ONLY) || (mode == OpusMode.MODE_CELT_ONLY && prev_mode != OpusMode.MODE_CELT_ONLY))) { num3 = 1; num5 = ((mode != OpusMode.MODE_CELT_ONLY) ? 1 : 0); if (num5 == 0) { if (frame_size >= Fs / 100) { mode = prev_mode; num6 = 1; } else { num3 = 0; } } } if (silk_bw_switch != 0) { num3 = 1; num5 = 1; silk_bw_switch = 0; num2 = 1; } if (num3 != 0) { num4 = Inlines.IMIN(257, num9 * (Fs / 200) / (frame_size + Fs / 200)); if (use_vbr != 0) { num4 = Inlines.IMIN(num4, bitrate_bps / 1600); } } if (mode != OpusMode.MODE_CELT_ONLY && prev_mode == OpusMode.MODE_CELT_ONLY) { EncControlState encStatus = new EncControlState(); EncodeAPI.silk_InitEncoder(silkEncoder, encStatus); num2 = 1; } if (mode == OpusMode.MODE_CELT_ONLY || first != 0 || silk_mode.allowBandwidthSwitch != 0) { int[] array = new int[8]; OpusBandwidth opusBandwidth2 = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; int num24 = num18; if (mode != OpusMode.MODE_CELT_ONLY) { num24 = num24 * (45 + silk_mode.complexity) / 50; if (use_vbr == 0) { num24 -= 1000; } } int[] array2; int[] array3; if (channels == 2 && force_channels != 1) { array2 = Tables.stereo_voice_bandwidth_thresholds; array3 = Tables.stereo_music_bandwidth_thresholds; } else { array2 = Tables.mono_voice_bandwidth_thresholds; array3 = Tables.mono_music_bandwidth_thresholds; } for (int i = 0; i < 8; i++) { array[i] = array3[i] + (num19 * num19 * (array2[i] - array3[i]) >> 14); } int num25; do { num25 = array[2 * (int)(opusBandwidth2 - 1102)]; int num26 = array[2 * (int)(opusBandwidth2 - 1102) + 1]; if (first == 0) { num25 = ((bandwidth < opusBandwidth2) ? (num25 + num26) : (num25 - num26)); } } while (num24 < num25 && --opusBandwidth2 > OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND); bandwidth = opusBandwidth2; if (first == 0 && mode != OpusMode.MODE_CELT_ONLY && silk_mode.inWBmodeWithoutVariableLP == 0 && bandwidth > OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } } if (bandwidth > max_bandwidth) { bandwidth = max_bandwidth; } if (user_bandwidth != OpusBandwidth.OPUS_BANDWIDTH_AUTO) { bandwidth = user_bandwidth; } if (mode != OpusMode.MODE_CELT_ONLY && num17 < 15000) { bandwidth = OpusBandwidthHelpers.MIN(bandwidth, OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND); } if (Fs <= 24000 && bandwidth > OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND; } if (Fs <= 16000 && bandwidth > OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } if (Fs <= 12000 && bandwidth > OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND; } if (Fs <= 8000 && bandwidth > OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } if (detected_bandwidth != 0 && user_bandwidth == OpusBandwidth.OPUS_BANDWIDTH_AUTO) { detected_bandwidth = OpusBandwidthHelpers.MAX(b: (num18 <= 18000 * stream_channels && mode == OpusMode.MODE_CELT_ONLY) ? OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND : ((num18 <= 24000 * stream_channels && mode == OpusMode.MODE_CELT_ONLY) ? OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND : ((num18 <= 30000 * stream_channels) ? OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND : ((num18 > 44000 * stream_channels) ? OpusBandwidth.OPUS_BANDWIDTH_FULLBAND : OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND))), a: detected_bandwidth); bandwidth = OpusBandwidthHelpers.MIN(bandwidth, detected_bandwidth); } celt_Encoder.SetLSBDepth(lsb_depth); if (mode == OpusMode.MODE_CELT_ONLY && bandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } if (lfe != 0) { bandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } if (frame_size > Fs / 50 && (mode == OpusMode.MODE_CELT_ONLY || bandwidth > OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND)) { if (analysis.enabled && num8 != -1) { analysis.read_pos = num8; analysis.read_subframe = read_subframe; } int num27 = ((frame_size > Fs / 25) ? 3 : 2); int num28 = Inlines.IMIN(1276, (out_data_bytes - 3) / num27); byte[] array4 = new byte[num27 * num28]; OpusRepacketizer opusRepacketizer = new OpusRepacketizer(); OpusMode opusMode2 = user_forced_mode; OpusBandwidth opusBandwidth3 = user_bandwidth; int num29 = force_channels; user_forced_mode = mode; user_bandwidth = bandwidth; force_channels = stream_channels; int toMono = silk_mode.toMono; if (toMono != 0) { force_channels = 1; } else { prev_channels = stream_channels; } for (int i = 0; i < num27; i++) { silk_mode.toMono = 0; if (num6 != 0 && i == num27 - 1) { user_forced_mode = OpusMode.MODE_CELT_ONLY; } int num30 = opus_encode_native(pcm, pcm_ptr + i * (channels * Fs / 50), Fs / 50, array4, i * num28, num28, lsb_depth, null, 0, c1, c2, analysis_channels, downmix, float_api); if (num30 < 0) { return -3; } num = opusRepacketizer.AddPacket(array4, i * num28, num30); if (num < 0) { return -3; } } num = opusRepacketizer.opus_repacketizer_out_range_impl(maxlen: (use_vbr == 0) ? Inlines.IMIN(3 * bitrate_bps / (1200 / num27), out_data_bytes) : out_data_bytes, begin: 0, end: num27, data: data, data_ptr: data_ptr, self_delimited: 0, pad: (use_vbr == 0) ? 1 : 0); if (num < 0) { return -3; } user_forced_mode = opusMode2; user_bandwidth = opusBandwidth3; force_channels = num29; silk_mode.toMono = toMono; return num; } OpusBandwidth opusBandwidth4 = bandwidth; if (mode == OpusMode.MODE_SILK_ONLY && opusBandwidth4 > OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { mode = OpusMode.MODE_HYBRID; } if (mode == OpusMode.MODE_HYBRID && opusBandwidth4 <= OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND) { mode = OpusMode.MODE_SILK_ONLY; } int num31 = Inlines.IMIN(num9 - num4, bitrate_bps * frame_size / (Fs * 8)) - 1; data_ptr++; entropyCoder.enc_init((uint)(num9 - 1)); short[] array5 = new short[(num13 + frame_size) * channels]; Arrays.MemCopy(delay_buffer, (encoder_buffer - num13) * channels, array5, 0, num13 * channels); variable_HP_smth2_Q15 = Inlines.silk_SMLAWB(b32: ((mode != OpusMode.MODE_CELT_ONLY) ? silkEncoder.state_Fxx[0].variable_HP_smth1_Q15 : Inlines.silk_LSHIFT(Inlines.silk_lin2log(60), 8)) - variable_HP_smth2_Q15, a32: variable_HP_smth2_Q15, c32: 983); int cutoff_Hz = Inlines.silk_log2lin(Inlines.silk_RSHIFT(variable_HP_smth2_Q15, 8)); if (application == OpusApplication.OPUS_APPLICATION_VOIP) { CodecHelpers.hp_cutoff(pcm, pcm_ptr, cutoff_Hz, array5, num13 * channels, hp_mem, frame_size, channels, Fs); } else { CodecHelpers.dc_reject(pcm, pcm_ptr, 3, array5, num13 * channels, hp_mem, frame_size, channels, Fs); } int num32 = 32767; if (mode != OpusMode.MODE_CELT_ONLY) { short[] array6 = new short[channels * frame_size]; int num33 = 8 * num31 * num14; if (mode == OpusMode.MODE_HYBRID) { silk_mode.bitRate = stream_channels * (5000 + ((Fs == 100 * frame_size) ? 1000 : 0)); if (opusBandwidth4 == OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) { silk_mode.bitRate += (num33 - silk_mode.bitRate) * 2 / 3; } else { silk_mode.bitRate += (num33 - silk_mode.bitRate) * 3 / 5; } if (silk_mode.bitRate > num33 * 4 / 5) { silk_mode.bitRate = num33 * 4 / 5; } if (energy_masking == null) { int num34 = num33 - silk_mode.bitRate; int num35 = ((opusBandwidth4 == OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600); num32 = Inlines.SHL32(num34, 9) / Inlines.SHR32(num34 + stream_channels * num35, 6); num32 = ((num32 < 28086) ? (num32 + 4681) : 32767); } } else { silk_mode.bitRate = num33; } if (energy_masking != null && use_vbr != 0 && lfe == 0) { int num36 = 0; int num37 = 17; short a = 16000; if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND) { num37 = 13; a = 8000; } else if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { num37 = 15; a = 12000; } for (int j = 0; j < channels; j++) { for (int i = 0; i < num37; i++) { int num38 = Inlines.MAX16(Inlines.MIN16(energy_masking[21 * j + i], 512), -2048); if (num38 > 0) { num38 = Inlines.HALF16(num38); } num36 += num38; } } int num39 = num36 / num37 * channels; num39 += 205; int a2 = Inlines.PSHR32(Inlines.MULT16_16(a, num39), 10); a2 = Inlines.MAX32(a2, -2 * silk_mode.bitRate / 3); if (bandwidth == OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND || bandwidth == OpusBandwidth.OPUS_BANDWIDTH_FULLBAND) { silk_mode.bitRate += 3 * a2 / 5; } else { silk_mode.bitRate += a2; } num31 += a2 * frame_size / (8 * Fs); } silk_mode.payloadSize_ms = 1000 * frame_size / Fs; silk_mode.nChannelsAPI = channels; silk_mode.nChannelsInternal = stream_channels; switch (opusBandwidth4) { case OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND: silk_mode.desiredInternalSampleRate = 8000; break; case OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND: silk_mode.desiredInternalSampleRate = 12000; break; default: silk_mode.desiredInternalSampleRate = 16000; break; } if (mode == OpusMode.MODE_HYBRID) { silk_mode.minInternalSampleRate = 16000; } else { silk_mode.minInternalSampleRate = 8000; } if (mode == OpusMode.MODE_SILK_ONLY) { int num40 = num17; silk_mode.maxInternalSampleRate = 16000; if (num14 > 50) { num40 = num40 * 2 / 3; } if (num40 < 13000) { silk_mode.maxInternalSampleRate = 12000; silk_mode.desiredInternalSampleRate = Inlines.IMIN(12000, silk_mode.desiredInternalSampleRate); } if (num40 < 9600) { silk_mode.maxInternalSampleRate = 8000; silk_mode.desiredInternalSampleRate = Inlines.IMIN(8000, silk_mode.desiredInternalSampleRate); } } else { silk_mode.maxInternalSampleRate = 16000; } silk_mode.useCBR = ((use_vbr == 0) ? 1 : 0); int num41 = Inlines.IMIN(1275, num9 - 1 - num4); silk_mode.maxBits = num41 * 8; if (mode == OpusMode.MODE_HYBRID) { silk_mode.maxBits = silk_mode.maxBits * 9 / 10; } if (silk_mode.useCBR != 0) { silk_mode.maxBits = silk_mode.bitRate * frame_size / (Fs * 8) * 8; silk_mode.bitRate = Inlines.IMAX(1, silk_mode.bitRate - 2000); } if (num2 != 0) { BoxedValueInt nBytesOut = new BoxedValueInt(); int num42 = channels * (encoder_buffer - delay_compensation - Fs / 400); CodecHelpers.gain_fade(delay_buffer, num42, 0, 32767, celtMode.overlap, Fs / 400, channels, celtMode.window, Fs); Arrays.MemSetShort(delay_buffer, 0, num42); Arrays.MemCopy(delay_buffer, 0, array6, 0, encoder_buffer * channels); EncodeAPI.silk_Encode(silkEncoder, silk_mode, array6, encoder_buffer, null, data.Slice(data_ptr), nBytesOut, 1); } Arrays.MemCopy(array5, num13 * channels, array6, 0, frame_size * channels); BoxedValueInt boxedValueInt = new BoxedValueInt(num41); num = EncodeAPI.silk_Encode(silkEncoder, silk_mode, array6, frame_size, entropyCoder, data.Slice(data_ptr), boxedValueInt, 0); num41 = boxedValueInt.Val; if (num != 0) { return -3; } if (num41 == 0) { rangeFinal = 0u; data[data_ptr - 1] = CodecHelpers.gen_toc(mode, Fs / frame_size, opusBandwidth4, stream_channels); return 1; } if (mode == OpusMode.MODE_SILK_ONLY) { if (silk_mode.internalSampleRate == 8000) { opusBandwidth4 = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } else if (silk_mode.internalSampleRate == 12000) { opusBandwidth4 = OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND; } else if (silk_mode.internalSampleRate == 16000) { opusBandwidth4 = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } } silk_mode.opusCanSwitch = silk_mode.switchReady; if (silk_mode.opusCanSwitch != 0) { num3 = 1; num5 = 0; silk_bw_switch = 1; } } int endBand = 21; switch (opusBandwidth4) { case OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND: endBand = 13; break; case OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND: case OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND: endBand = 17; break; case OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND: endBand = 19; break; case OpusBandwidth.OPUS_BANDWIDTH_FULLBAND: endBand = 21; break; } celt_Encoder.SetEndBand(endBand); celt_Encoder.SetChannels(stream_channels); celt_Encoder.SetBitrate(-1); int num44; if (mode != OpusMode.MODE_SILK_ONLY) { int prediction = 2; celt_Encoder.SetVBR(value: false); if (silk_mode.reducedDependency != 0) { prediction = 0; } celt_Encoder.SetPrediction(prediction); if (mode == OpusMode.MODE_HYBRID) { int num43 = entropyCoder.tell() + 7 >> 3; if (num3 != 0) { num43 += ((mode != OpusMode.MODE_HYBRID) ? 1 : 3); } num44 = ((use_vbr == 0) ? ((num43 > num31) ? num43 : num31) : (num43 + num31 - silk_mode.bitRate * frame_size / (8 * Fs))); } else if (use_vbr != 0) { int num45 = 0; if (analysis.enabled && variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE && frame_size != Fs / 50) { num45 = (60 * stream_channels + 40) * (Fs / frame_size - 50); if (analysisInfo.valid != 0) { num45 = (int)((float)num45 * (1f + 0.5f * analysisInfo.tonality)); } } celt_Encoder.SetVBR(value: true); celt_Encoder.SetVBRConstraint(vbr_constraint != 0); celt_Encoder.SetBitrate(bitrate_bps + num45); num44 = num9 - 1 - num4; } else { num44 = num31; } } else { num44 = 0; } short[] array7 = new short[channels * Fs / 400]; if (mode != OpusMode.MODE_SILK_ONLY && mode != prev_mode && prev_mode > (OpusMode)0) { Arrays.MemCopy(delay_buffer, (encoder_buffer - num13 - Fs / 400) * channels, array7, 0, channels * Fs / 400); } if (channels * (encoder_buffer - (frame_size + num13)) > 0) { Arrays.MemMoveShort(delay_buffer, channels * frame_size, 0, channels * (encoder_buffer - frame_size - num13)); Arrays.MemCopy(array5, 0, delay_buffer, channels * (encoder_buffer - frame_size - num13), (frame_size + num13) * channels); } else { Arrays.MemCopy(array5, (frame_size + num13 - encoder_buffer) * channels, delay_buffer, 0, encoder_buffer * channels); } if (prev_HB_gain < 32767 || num32 < 32767) { CodecHelpers.gain_fade(array5, 0, prev_HB_gain, num32, celtMode.overlap, frame_size, channels, celtMode.window, Fs); } prev_HB_gain = num32; if (mode != OpusMode.MODE_HYBRID || stream_channels == 1) { silk_mode.stereoWidth_Q14 = Inlines.IMIN(16384, 2 * Inlines.IMAX(0, num18 - 30000)); } if (energy_masking == null && channels == 2 && (hybrid_stereo_width_Q14 < 16384 || silk_mode.stereoWidth_Q14 < 16384)) { int num46 = hybrid_stereo_width_Q14; int stereoWidth_Q = silk_mode.stereoWidth_Q14; num46 = ((num46 == 16384) ? 32767 : Inlines.SHL16(num46, 1)); stereoWidth_Q = ((stereoWidth_Q == 16384) ? 32767 : Inlines.SHL16(stereoWidth_Q, 1)); CodecHelpers.stereo_fade(array5, num46, stereoWidth_Q, celtMode.overlap, frame_size, channels, celtMode.window, Fs); hybrid_stereo_width_Q14 = (short)silk_mode.stereoWidth_Q14; } if (mode != OpusMode.MODE_CELT_ONLY && entropyCoder.tell() + 17 + 20 * ((mode == OpusMode.MODE_HYBRID) ? 1 : 0) <= 8 * (num9 - 1)) { if (mode == OpusMode.MODE_HYBRID && (num3 != 0 || entropyCoder.tell() + 37 <= 8 * num44)) { entropyCoder.enc_bit_logp(data.Slice(data_ptr), num3, 12u); } if (num3 != 0) { entropyCoder.enc_bit_logp(data.Slice(data_ptr), num5, 1u); int a3 = ((mode != OpusMode.MODE_HYBRID) ? (num9 - 1 - (entropyCoder.tell() + 7 >> 3)) : (num9 - 1 - num44)); num4 = Inlines.IMIN(a3, bitrate_bps / 1600); num4 = Inlines.IMIN(257, Inlines.IMAX(2, num4)); if (mode == OpusMode.MODE_HYBRID) { entropyCoder.enc_uint(data.Slice(data_ptr), (uint)(num4 - 2), 256u); } } } else { num3 = 0; } if (num3 == 0) { silk_bw_switch = 0; num4 = 0; } if (mode != OpusMode.MODE_CELT_ONLY) { startBand = 17; } if (mode == OpusMode.MODE_SILK_ONLY) { num = entropyCoder.tell() + 7 >> 3; entropyCoder.enc_done(data.Slice(data_ptr)); num44 = num; } else { num44 = Inlines.IMIN(num9 - 1 - num4, num44); entropyCoder.enc_shrink(data.Slice(data_ptr), (uint)num44); } if ((analysis.enabled && num3 != 0) || mode != OpusMode.MODE_SILK_ONLY) { celt_Encoder.SetAnalysis(analysisInfo); } if (num3 != 0 && num5 != 0) { celt_Encoder.SetStartBand(0); celt_Encoder.SetVBR(value: false); if (celt_Encoder.celt_encode_with_ec(array5, 0, Fs / 200, data, data_ptr + num44, num4, null) < 0) { return -3; } num7 = celt_Encoder.GetFinalRange(); celt_Encoder.ResetState(); } celt_Encoder.SetStartBand(startBand); if (mode != OpusMode.MODE_SILK_ONLY) { if (mode != prev_mode && prev_mode > (OpusMode)0) { Span compressed = stackalloc byte[2]; celt_Encoder.ResetState(); celt_Encoder.celt_encode_with_ec(array7, 0, Fs / 400, compressed, 0, 2, null); celt_Encoder.SetPrediction(0); } if (entropyCoder.tell() <= 8 * num44) { num = celt_Encoder.celt_encode_with_ec(array5, 0, frame_size, data.Slice(data_ptr), 0, num44, entropyCoder); if (num < 0) { return -3; } } } if (num3 != 0 && num5 == 0) { Span compressed2 = stackalloc byte[2]; int num47 = Fs / 200; int num48 = Fs / 400; celt_Encoder.ResetState(); celt_Encoder.SetStartBand(0); celt_Encoder.SetPrediction(0); celt_Encoder.celt_encode_with_ec(array5, channels * (frame_size - num47 - num48), num48, compressed2, 0, 2, null); if (celt_Encoder.celt_encode_with_ec(array5, channels * (frame_size - num47), num47, data, data_ptr + num44, num4, null) < 0) { return -3; } num7 = celt_Encoder.GetFinalRange(); } data_ptr--; data[data_ptr] = CodecHelpers.gen_toc(mode, Fs / frame_size, opusBandwidth4, stream_channels); rangeFinal = entropyCoder.rng ^ num7; if (num6 != 0) { prev_mode = OpusMode.MODE_CELT_ONLY; } else { prev_mode = mode; } prev_channels = stream_channels; prev_framesize = frame_size; first = 0; if (entropyCoder.tell() > (num9 - 1) * 8) { if (num9 < 2) { return -2; } data[data_ptr + 1] = 0; num = 1; rangeFinal = 0u; } else if (mode == OpusMode.MODE_SILK_ONLY && num3 == 0) { while (num > 2 && data[data_ptr + num] == 0) { num--; } } num += 1 + num4; if (use_vbr == 0) { if (OpusRepacketizer.PadPacket(data, data_ptr, num, num9) != 0) { return -3; } num = num9; } return num; } private static int GetVariableQualityBitrate(int vqLevel, float music_prob) { float num = vqTable[vqLevel][0]; float num2 = vqTable[vqLevel][1]; float num3 = (float)Math.Sqrt(music_prob); return (int)(num2 * num3 + num * (1f - num3)); } [Obsolete("Use Span<> overrides if possible")] public int Encode(short[] in_pcm, int pcm_offset, int frame_size, byte[] out_data, int out_data_offset, int max_data_bytes) { return Encode(MemoryExtensions.AsSpan(in_pcm, pcm_offset), frame_size, MemoryExtensions.AsSpan(out_data, out_data_offset), max_data_bytes); } public int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { if (max_data_bytes > out_data.Length) { throw new ArgumentException($"Output buffer is too small: Stated size is {max_data_bytes} bytes, actual size is {out_data.Length} bytes"); } int num = CodecHelpers.compute_frame_size(delay_compensation: (application != OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY) ? delay_compensation : 0, analysis_pcm: in_pcm, frame_size: frame_size, variable_duration: variable_duration, C: channels, Fs: Fs, bitrate_bps: bitrate_bps, downmix: Downmix.downmix_int, subframe_mem: analysis.subframe_mem, analysis_enabled: analysis.enabled); if (num > in_pcm.Length) { throw new ArgumentException($"Not enough samples provided in input signal: Expected {num} samples, found {in_pcm.Length}"); } try { int num2 = opus_encode_native(in_pcm, 0, num, out_data, 0, max_data_bytes, 16, in_pcm, frame_size, 0, -2, channels, Downmix.downmix_int, 0); if (num2 < 0) { if (num2 == -1) { throw new ArgumentException("OPUS_BAD_ARG while encoding"); } throw new OpusException("An error occurred during encoding: " + CodecHelpers.opus_strerror(num2), num2); } return num2; } catch (ArgumentException ex) { throw new OpusException("public error during encoding: " + ex.Message, -1); } } [Obsolete("Use Span<> overrides if possible")] public int Encode(float[] in_pcm, int in_pcm_offset, int frame_size, byte[] out_data, int out_data_offset, int max_data_bytes) { return Encode(MemoryExtensions.AsSpan(in_pcm, in_pcm_offset), frame_size, MemoryExtensions.AsSpan(out_data, out_data_offset), max_data_bytes); } public int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { if (max_data_bytes > out_data.Length) { throw new ArgumentException($"Output buffer is too small: Stated size is {max_data_bytes} bytes, actual size is {out_data.Length} bytes"); } int num = CodecHelpers.compute_frame_size(delay_compensation: (application != OpusApplication.OPUS_APPLICATION_RESTRICTED_LOWDELAY) ? delay_compensation : 0, analysis_pcm: in_pcm, frame_size: frame_size, variable_duration: variable_duration, C: channels, Fs: Fs, bitrate_bps: bitrate_bps, downmix: Downmix.downmix_float, subframe_mem: analysis.subframe_mem, analysis_enabled: analysis.enabled); if (num > in_pcm.Length) { throw new ArgumentException($"Not enough samples provided in input signal: Expected {num} samples, found {in_pcm.Length}"); } short[] array = new short[num * channels]; for (int i = 0; i < num * channels; i++) { array[i] = Inlines.FLOAT2INT16(in_pcm[i]); } try { int num2 = opus_encode_native(array, 0, num, out_data, 0, max_data_bytes, 16, in_pcm, frame_size, 0, -2, channels, Downmix.downmix_float, 1); if (num2 < 0) { if (num2 == -1) { throw new ArgumentException("OPUS_BAD_ARG while decoding"); } throw new OpusException("An error occurred during encoding: " + CodecHelpers.opus_strerror(num2), num2); } return num2; } catch (ArgumentException ex) { throw new OpusException("public error during encoding: " + ex.Message, -1); } } internal void SetEnergyMask(int[] value) { energy_masking = value; Celt_Encoder.SetEnergyMask(value); } internal CeltMode GetCeltMode() { return Celt_Encoder.GetMode(); } public string GetVersionString() { return CodecHelpers.GetVersionString(); } public void Dispose() { } } internal class OpusMSDecoder : IOpusMultiStreamDecoder, IDisposable { internal delegate void opus_copy_channel_out_func(Span dst, int dst_stride, int dst_channel, Span src, int src_ptr, int src_stride, int frame_size); internal ChannelLayout layout = new ChannelLayout(); internal OpusDecoder[] decoders; public OpusBandwidth Bandwidth { get { if (decoders == null || decoders.Length == 0) { throw new InvalidOperationException("Decoder not initialized"); } return decoders[0].Bandwidth; } } public int SampleRate { get { if (decoders == null || decoders.Length == 0) { throw new InvalidOperationException("Decoder not initialized"); } return decoders[0].SampleRate; } } public int NumChannels => layout.nb_channels; public int Gain { get { if (decoders == null || decoders.Length == 0) { return -6; } return decoders[0].Gain; } set { for (int i = 0; i < layout.nb_streams; i++) { decoders[i].Gain = value; } } } public int LastPacketDuration { get { if (decoders == null || decoders.Length == 0) { return -6; } return decoders[0].LastPacketDuration; } } public uint FinalRange { get { uint num = 0u; for (int i = 0; i < layout.nb_streams; i++) { num ^= decoders[i].FinalRange; } return num; } } private OpusMSDecoder(int nb_streams, int nb_coupled_streams) { decoders = new OpusDecoder[nb_streams]; for (int i = 0; i < nb_streams; i++) { decoders[i] = new OpusDecoder(); } } internal int opus_multistream_decoder_init(int Fs, int channels, int streams, int coupled_streams, byte[] mapping) { int num = 0; if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) { throw new ArgumentException("Invalid channel or coupled stream count"); } layout.nb_channels = channels; layout.nb_streams = streams; layout.nb_coupled_streams = coupled_streams; int i; for (i = 0; i < layout.nb_channels; i++) { layout.mapping[i] = mapping[i]; } if (OpusMultistream.validate_layout(layout) == 0) { throw new ArgumentException("Invalid surround channel layout"); } for (i = 0; i < layout.nb_coupled_streams; i++) { int num2 = decoders[num].opus_decoder_init(Fs, 2); if (num2 != 0) { return num2; } num++; } for (; i < layout.nb_streams; i++) { int num2 = decoders[num].opus_decoder_init(Fs, 1); if (num2 != 0) { return num2; } num++; } return 0; } [Obsolete("Use OpusCodecFactory methods which can give you native code if supported by your platform")] public OpusMSDecoder(int Fs, int channels, int streams, int coupled_streams, byte[] mapping) : this(streams, coupled_streams) { if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) { throw new ArgumentException("Invalid channel / stream configuration"); } int num = opus_multistream_decoder_init(Fs, channels, streams, coupled_streams, mapping); switch (num) { case -1: throw new ArgumentException("Bad argument while creating MS decoder"); default: throw new OpusException("Could not create MS decoder: " + CodecHelpers.opus_strerror(num), num); case 0: break; } } internal static int opus_multistream_packet_validate(ReadOnlySpan data, int nb_streams, int Fs) { short[] array = new short[48]; int num = 0; int num2 = 0; int num3 = data.Length; for (int i = 0; i < nb_streams; i++) { if (data.Length <= 0) { return -4; } byte out_toc; int payload_offset; int packet_offset; int num4 = OpusPacketInfo.opus_packet_parse_impl(data, num2, num3, (i != nb_streams - 1) ? 1 : 0, out out_toc, null, null, 0, array, 0, out payload_offset, out packet_offset); if (num4 < 0) { return num4; } int numSamples = OpusPacketInfo.GetNumSamples(data.Slice(num2, packet_offset), Fs); if (i != 0 && num != numSamples) { return -4; } num = numSamples; num2 += packet_offset; num3 -= packet_offset; } return num; } internal int opus_multistream_decode_native(ReadOnlySpan data, Span pcm, opus_copy_channel_out_func copy_channel_out, int frame_size, int decode_fec, int soft_clip) { int num = 0; int sampleRate = SampleRate; frame_size = Inlines.IMIN(frame_size, sampleRate / 25 * 3); short[] array = new short[2 * frame_size]; int num2 = 0; if (data.Length == 0) { num = 1; } if (data.Length < 0) { return -1; } if (num == 0 && data.Length < 2 * layout.nb_streams - 1) { return -4; } if (num == 0) { int num3 = opus_multistream_packet_validate(data, layout.nb_streams, sampleRate); if (num3 < 0) { return num3; } if (num3 > frame_size) { return -2; } } int num4 = 0; int num5 = data.Length; for (int i = 0; i < layout.nb_streams; i++) { OpusDecoder opusDecoder = decoders[num2++]; if (num == 0 && data.Length <= 0) { return -3; } int packet_offset; int num6 = opusDecoder.opus_decode_native(data, num4, num5, array, 0, frame_size, decode_fec, (i != layout.nb_streams - 1) ? 1 : 0, out packet_offset, soft_clip); num4 += packet_offset; num5 -= packet_offset; if (num6 <= 0) { return num6; } frame_size = num6; if (i < layout.nb_coupled_streams) { int prev = -1; int num7; while ((num7 = OpusMultistream.get_left_channel(layout, i, prev)) != -1) { copy_channel_out(pcm, layout.nb_channels, num7, array, 0, 2, frame_size); prev = num7; } prev = -1; while ((num7 = OpusMultistream.get_right_channel(layout, i, prev)) != -1) { copy_channel_out(pcm, layout.nb_channels, num7, array, 1, 2, frame_size); prev = num7; } } else { int prev2 = -1; int num8; while ((num8 = OpusMultistream.get_mono_channel(layout, i, prev2)) != -1) { copy_channel_out(pcm, layout.nb_channels, num8, array, 0, 1, frame_size); prev2 = num8; } } } for (int j = 0; j < layout.nb_channels; j++) { if (layout.mapping[j] == byte.MaxValue) { copy_channel_out(pcm, layout.nb_channels, j, null, 0, 0, frame_size); } } return frame_size; } internal static void opus_copy_channel_out_float(Span dst, int dst_stride, int dst_channel, Span src, int src_ptr, int src_stride, int frame_size) { if (!src.IsEmpty) { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_channel] = 3.0517578E-05f * (float)src[i * src_stride + src_ptr]; } } else { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_channel] = 0f; } } } internal static void opus_copy_channel_out_short(Span dst, int dst_stride, int dst_channel, Span src, int src_ptr, int src_stride, int frame_size) { if (!src.IsEmpty) { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_channel] = src[i * src_stride + src_ptr]; } } else { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_channel] = 0; } } } [Obsolete("Use Span<> overrides if possible")] public int DecodeMultistream(byte[] data, int data_offset, int len, short[] out_pcm, int out_pcm_offset, int frame_size, bool decode_fec) { if (data == null) { return DecodeMultistream(ReadOnlySpan.Empty, MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } return DecodeMultistream(MemoryExtensions.AsSpan(data, data_offset, len), MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } public int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec) { int num = opus_multistream_decode_native(data, out_pcm, opus_copy_channel_out_short, frame_size, decode_fec ? 1 : 0, 0); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG while decoding"); } throw new OpusException("An error occurred during decoding: " + CodecHelpers.opus_strerror(num), num); } return num; } [Obsolete("Use Span<> overrides if possible")] public int DecodeMultistream(byte[] data, int data_offset, int len, float[] out_pcm, int out_pcm_offset, int frame_size, bool decode_fec) { if (data == null) { return DecodeMultistream(ReadOnlySpan.Empty, MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } return DecodeMultistream(MemoryExtensions.AsSpan(data, data_offset, len), MemoryExtensions.AsSpan(out_pcm, out_pcm_offset), frame_size, decode_fec); } public int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec) { int num = opus_multistream_decode_native(data, out_pcm, opus_copy_channel_out_float, frame_size, decode_fec ? 1 : 0, 0); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG while decoding"); } throw new OpusException("An error occurred during decoding: " + CodecHelpers.opus_strerror(num), num); } return num; } public void ResetState() { for (int i = 0; i < layout.nb_streams; i++) { decoders[i].ResetState(); } } public string GetVersionString() { return CodecHelpers.GetVersionString(); } public OpusDecoder GetMultistreamDecoderState(int streamId) { return decoders[streamId]; } public void Dispose() { } } internal class OpusMSEncoder : IOpusMultiStreamEncoder, IDisposable { internal delegate void opus_copy_channel_in_func(Span dst, int dst_ptr, int dst_stride, ReadOnlySpan src, int src_stride, int src_channel, int frame_size); internal readonly ChannelLayout layout = new ChannelLayout(); internal int lfe_stream; internal OpusApplication application = OpusApplication.OPUS_APPLICATION_AUDIO; internal OpusFramesize variable_duration; internal int surround; internal int bitrate_bps; internal readonly float[] subframe_mem = new float[3]; internal readonly OpusEncoder[] encoders; internal readonly int[] window_mem; internal readonly int[] preemph_mem; private static readonly int[] diff_table = new int[17] { 512, 300, 165, 87, 45, 23, 11, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0 }; private const int MS_FRAME_TMP = 3832; public int Bitrate { get { int num = 0; int num2 = 0; for (int i = 0; i < layout.nb_streams; i++) { OpusEncoder opusEncoder = encoders[num2++]; num += opusEncoder.Bitrate; } return num; } set { if (value < 0 && value != -1000 && value != -1) { throw new ArgumentException("Invalid bitrate"); } bitrate_bps = value; } } public OpusApplication Application { get { return encoders[0].Application; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].Application = value; } } } public int ForceChannels { get { return encoders[0].ForceChannels; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].ForceChannels = value; } } } public int NumChannels => layout.nb_channels; public OpusBandwidth MaxBandwidth { get { return encoders[0].MaxBandwidth; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].MaxBandwidth = value; } } } public OpusBandwidth Bandwidth { get { return encoders[0].Bandwidth; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].Bandwidth = value; } } } public bool UseDTX { get { return encoders[0].UseDTX; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].UseDTX = value; } } } public int Complexity { get { return encoders[0].Complexity; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].Complexity = value; } } } public OpusMode ForceMode { get { return encoders[0].ForceMode; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].ForceMode = value; } } } public bool UseInbandFEC { get { return encoders[0].UseInbandFEC; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].UseInbandFEC = value; } } } public int PacketLossPercent { get { return encoders[0].PacketLossPercent; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].PacketLossPercent = value; } } } public bool UseVBR { get { return encoders[0].UseVBR; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].UseVBR = value; } } } public bool UseConstrainedVBR { get { return encoders[0].UseConstrainedVBR; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].UseConstrainedVBR = value; } } } public OpusSignal SignalType { get { return encoders[0].SignalType; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].SignalType = value; } } } public int Lookahead => encoders[0].Lookahead; public int SampleRate => encoders[0].SampleRate; public uint FinalRange { get { uint num = 0u; int num2 = 0; for (int i = 0; i < layout.nb_streams; i++) { num ^= encoders[num2++].FinalRange; } return num; } } public int LSBDepth { get { return encoders[0].LSBDepth; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].LSBDepth = value; } } } public bool PredictionDisabled { get { return encoders[0].PredictionDisabled; } set { for (int i = 0; i < layout.nb_streams; i++) { encoders[i].PredictionDisabled = value; } } } public OpusFramesize ExpertFrameDuration { get { return variable_duration; } set { variable_duration = value; } } private OpusMSEncoder(int nb_streams, int nb_coupled_streams) { if (nb_streams < 1 || nb_coupled_streams > nb_streams || nb_coupled_streams < 0) { throw new ArgumentException("Invalid channel count in MS encoder"); } encoders = new OpusEncoder[nb_streams]; for (int i = 0; i < nb_streams; i++) { encoders[i] = new OpusEncoder(); } int num = nb_coupled_streams * 2 + (nb_streams - nb_coupled_streams); window_mem = new int[num * 120]; preemph_mem = new int[num]; } public void ResetState() { subframe_mem[0] = (subframe_mem[1] = (subframe_mem[2] = 0f)); if (surround != 0) { Arrays.MemSetInt(preemph_mem, 0, layout.nb_channels); Arrays.MemSetInt(window_mem, 0, layout.nb_channels * 120); } int num = 0; for (int i = 0; i < layout.nb_streams; i++) { encoders[num++].ResetState(); } } internal static int validate_encoder_layout(ChannelLayout layout) { for (int i = 0; i < layout.nb_streams; i++) { if (i < layout.nb_coupled_streams) { if (OpusMultistream.get_left_channel(layout, i, -1) == -1) { return 0; } if (OpusMultistream.get_right_channel(layout, i, -1) == -1) { return 0; } } else if (OpusMultistream.get_mono_channel(layout, i, -1) == -1) { return 0; } } return 1; } internal static void channel_pos(int channels, int[] pos) { switch (channels) { case 4: pos[0] = 1; pos[1] = 3; pos[2] = 1; pos[3] = 3; break; case 3: case 5: case 6: pos[0] = 1; pos[1] = 2; pos[2] = 3; pos[3] = 1; pos[4] = 3; pos[5] = 0; break; case 7: pos[0] = 1; pos[1] = 2; pos[2] = 3; pos[3] = 1; pos[4] = 3; pos[5] = 2; pos[6] = 0; break; case 8: pos[0] = 1; pos[1] = 2; pos[2] = 3; pos[3] = 1; pos[4] = 3; pos[5] = 1; pos[6] = 3; pos[7] = 0; break; } } internal static int logSum(int a, int b) { int num; int num2; if (a > b) { num = a; num2 = Inlines.SUB32(Inlines.EXTEND32(a), Inlines.EXTEND32(b)); } else { num = b; num2 = Inlines.SUB32(Inlines.EXTEND32(b), Inlines.EXTEND32(a)); } if (num2 >= 8192) { return num; } int num3 = Inlines.SHR32(num2, 9); int a2 = Inlines.SHL16(num2 - Inlines.SHL16(num3, 9), 6); return num + diff_table[num3] + Inlines.MULT16_16_Q15(a2, Inlines.SUB16(diff_table[num3 + 1], diff_table[num3])); } internal static void surround_analysis(CeltMode celt_mode, ReadOnlySpan pcm, int[] bandLogE, int[] mem, int[] preemph_mem, int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in) { int[] array = new int[8]; int[][] array2 = Arrays.InitTwoDimensionalArray(1, 21); int[][] array3 = Arrays.InitTwoDimensionalArray(3, 21); int num = CeltCommon.resampling_factor(rate); int num2 = len * num; int i; for (i = 0; i < celt_mode.maxLM && celt_mode.shortMdctSize << i != num2; i++) { } int[] array4 = new int[num2 + overlap]; short[] array5 = new short[len]; int[][] array6 = Arrays.InitTwoDimensionalArray(1, num2); channel_pos(channels, array); for (int j = 0; j < 3; j++) { for (int k = 0; k < 21; k++) { array3[j][k] = -28672; } } for (int j = 0; j < channels; j++) { Arrays.MemCopy(mem, j * overlap, array4, 0, overlap); copy_channel_in(array5, 0, 1, pcm, channels, j, len); BoxedValueInt boxedValueInt = new BoxedValueInt(preemph_mem[j]); CeltCommon.celt_preemphasis(array5, array4, overlap, num2, 1, num, celt_mode.preemph, boxedValueInt, 0); preemph_mem[j] = boxedValueInt.Val; MDCT.clt_mdct_forward(celt_mode.mdct, array4, 0, array6[0], 0, celt_mode.window, overlap, celt_mode.maxLM - i, 1); if (num != 1) { int k; for (k = 0; k < len; k++) { array6[0][k] *= num; } for (; k < num2; k++) { array6[0][k] = 0; } } Bands.compute_band_energies(celt_mode, array6, array2, 21, 1, i); QuantizeBands.amp2Log2(celt_mode, 21, 21, array2[0], bandLogE, 21 * j, 1); for (int k = 1; k < 21; k++) { bandLogE[21 * j + k] = Inlines.MAX16(bandLogE[21 * j + k], bandLogE[21 * j + k - 1] - 1024); } for (int k = 19; k >= 0; k--) { bandLogE[21 * j + k] = Inlines.MAX16(bandLogE[21 * j + k], bandLogE[21 * j + k + 1] - 2048); } if (array[j] == 1) { for (int k = 0; k < 21; k++) { array3[0][k] = logSum(array3[0][k], bandLogE[21 * j + k]); } } else if (array[j] == 3) { for (int k = 0; k < 21; k++) { array3[2][k] = logSum(array3[2][k], bandLogE[21 * j + k]); } } else if (array[j] == 2) { for (int k = 0; k < 21; k++) { array3[0][k] = logSum(array3[0][k], bandLogE[21 * j + k] - 512); array3[2][k] = logSum(array3[2][k], bandLogE[21 * j + k] - 512); } } Arrays.MemCopy(array4, num2, mem, j * overlap, overlap); } for (int k = 0; k < 21; k++) { array3[1][k] = Inlines.MIN32(array3[0][k], array3[2][k]); } int num3 = Inlines.HALF16(Inlines.celt_log2(32768 / (channels - 1))); for (int j = 0; j < 3; j++) { for (int k = 0; k < 21; k++) { array3[j][k] += num3; } } for (int j = 0; j < channels; j++) { if (array[j] != 0) { int[] array7 = array3[array[j] - 1]; for (int k = 0; k < 21; k++) { bandLogE[21 * j + k] -= array7[k]; } } else { for (int k = 0; k < 21; k++) { bandLogE[21 * j + k] = 0; } } } } internal int opus_multistream_encoder_init(int Fs, int channels, int streams, int coupled_streams, byte[] mapping, OpusApplication application, int surround) { if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) { return -1; } layout.nb_channels = channels; layout.nb_streams = streams; layout.nb_coupled_streams = coupled_streams; subframe_mem[0] = (subframe_mem[1] = (subframe_mem[2] = 0f)); if (surround == 0) { lfe_stream = -1; } bitrate_bps = -1000; this.application = application; variable_duration = OpusFramesize.OPUS_FRAMESIZE_ARG; int i; for (i = 0; i < layout.nb_channels; i++) { layout.mapping[i] = mapping[i]; } if (OpusMultistream.validate_layout(layout) == 0 || validate_encoder_layout(layout) == 0) { return -1; } int num = 0; for (i = 0; i < layout.nb_coupled_streams; i++) { int num2 = encoders[num].opus_init_encoder(Fs, 2, application); if (num2 != 0) { return num2; } if (i == lfe_stream) { encoders[num].IsLFE = true; } num++; } for (; i < layout.nb_streams; i++) { int num2 = encoders[num].opus_init_encoder(Fs, 1, application); if (i == lfe_stream) { encoders[num].IsLFE = true; } if (num2 != 0) { return num2; } num++; } if (surround != 0) { Arrays.MemSetInt(preemph_mem, 0, channels); Arrays.MemSetInt(window_mem, 0, channels * 120); } this.surround = surround; return 0; } internal int opus_multistream_surround_encoder_init(int Fs, int channels, int mapping_family, out int streams, out int coupled_streams, byte[] mapping, OpusApplication application) { streams = 0; coupled_streams = 0; if (channels > 255 || channels < 1) { return -1; } lfe_stream = -1; if (mapping_family == 0) { switch (channels) { case 1: streams = 1; coupled_streams = 0; mapping[0] = 0; break; case 2: streams = 1; coupled_streams = 1; mapping[0] = 0; mapping[1] = 1; break; default: return -5; } } else if (mapping_family == 1 && channels <= 8 && channels >= 1) { streams = VorbisLayout.vorbis_mappings[channels - 1].nb_streams; coupled_streams = VorbisLayout.vorbis_mappings[channels - 1].nb_coupled_streams; for (int i = 0; i < channels; i++) { mapping[i] = VorbisLayout.vorbis_mappings[channels - 1].mapping[i]; } if (channels >= 6) { lfe_stream = streams - 1; } } else { if (mapping_family != 255) { return -5; } streams = channels; coupled_streams = 0; for (byte b = 0; b < channels; b++) { mapping[b] = b; } } return opus_multistream_encoder_init(Fs, channels, streams, coupled_streams, mapping, application, (channels > 2 && mapping_family == 1) ? 1 : 0); } [Obsolete("Use OpusCodecFactory methods which can give you native code if supported by your platform")] public static OpusMSEncoder Create(int Fs, int channels, int streams, int coupled_streams, byte[] mapping, OpusApplication application) { if (channels > 255 || channels < 1 || coupled_streams > streams || streams < 1 || coupled_streams < 0 || streams > 255 - coupled_streams) { throw new ArgumentException("Invalid channel / stream configuration"); } OpusMSEncoder opusMSEncoder = new OpusMSEncoder(streams, coupled_streams); int num = opusMSEncoder.opus_multistream_encoder_init(Fs, channels, streams, coupled_streams, mapping, application, 0); return num switch { -1 => throw new ArgumentException("OPUS_BAD_ARG when creating MS encoder"), 0 => opusMSEncoder, _ => throw new OpusException("Could not create MS encoder: " + CodecHelpers.opus_strerror(num), num), }; } internal static void GetStreamCount(int channels, int mapping_family, BoxedValueInt nb_streams, BoxedValueInt nb_coupled_streams) { switch (mapping_family) { case 0: switch (channels) { case 1: nb_streams.Val = 1; nb_coupled_streams.Val = 0; break; case 2: nb_streams.Val = 1; nb_coupled_streams.Val = 1; break; default: throw new ArgumentException("More than 2 channels requires custom mappings"); } return; case 1: if (channels <= 8 && channels >= 1) { nb_streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_streams; nb_coupled_streams.Val = VorbisLayout.vorbis_mappings[channels - 1].nb_coupled_streams; return; } break; } if (mapping_family == 255) { nb_streams.Val = channels; nb_coupled_streams.Val = 0; return; } throw new ArgumentException("Invalid mapping family"); } [Obsolete("Use OpusCodecFactory methods which can give you native code if supported by your platform")] public static OpusMSEncoder CreateSurround(int Fs, int channels, int mapping_family, out int streams, out int coupled_streams, byte[] mapping, OpusApplication application) { if (channels > 255 || channels < 1 || application == OpusApplication.OPUS_APPLICATION_UNIMPLEMENTED) { throw new ArgumentException("Invalid channel count or application"); } BoxedValueInt boxedValueInt = new BoxedValueInt(); BoxedValueInt boxedValueInt2 = new BoxedValueInt(); GetStreamCount(channels, mapping_family, boxedValueInt, boxedValueInt2); OpusMSEncoder opusMSEncoder = new OpusMSEncoder(boxedValueInt.Val, boxedValueInt2.Val); int num = opusMSEncoder.opus_multistream_surround_encoder_init(Fs, channels, mapping_family, out streams, out coupled_streams, mapping, application); return num switch { -1 => throw new ArgumentException("Bad argument passed to CreateSurround"), 0 => opusMSEncoder, _ => throw new OpusException("Could not create multistream encoder: " + CodecHelpers.opus_strerror(num), num), }; } internal int surround_rate_allocation(int[] out_rates, int frame_size) { int num = 0; int sampleRate = encoders[0].SampleRate; int num2 = ((bitrate_bps <= layout.nb_channels * 40000) ? (bitrate_bps / layout.nb_channels / 2) : 20000); num2 += 60 * (sampleRate / frame_size - 50); int num3 = 3500 + 60 * (sampleRate / frame_size - 50); int num4 = 512; int num5 = 32; int num6; if (bitrate_bps == -1000) { num6 = sampleRate + 60 * sampleRate / frame_size; } else if (bitrate_bps == -1) { num6 = 300000; } else { int num7 = ((lfe_stream != -1) ? 1 : 0); int nb_coupled_streams = layout.nb_coupled_streams; int num8 = layout.nb_streams - nb_coupled_streams - num7; int num9 = (num8 << 8) + num4 * nb_coupled_streams + num7 * num5; num6 = 256 * (bitrate_bps - num3 * num7 - num2 * (nb_coupled_streams + num8)) / num9; } for (int i = 0; i < layout.nb_streams; i++) { if (i < layout.nb_coupled_streams) { out_rates[i] = num2 + (num6 * num4 >> 8); } else if (i != lfe_stream) { out_rates[i] = num2 + num6; } else { out_rates[i] = num3 + (num6 * num5 >> 8); } out_rates[i] = Inlines.IMAX(out_rates[i], 500); num += out_rates[i]; } return num; } internal int opus_multistream_encode_native(opus_copy_channel_in_func copy_channel_in, ReadOnlySpan pcm, int analysis_frame_size, Span data, int max_data_bytes, int lsb_depth, Downmix.downmix_func downmix, int float_api) { byte[] array = new byte[3832]; OpusRepacketizer opusRepacketizer = new OpusRepacketizer(); int[] array2 = new int[256]; int[] array3 = new int[42]; int[] mem = null; int[] array4 = null; int num = 0; if (surround != 0) { array4 = preemph_mem; mem = window_mem; } int num2 = 0; int sampleRate = encoders[num2].SampleRate; int num3 = (encoders[num2].UseVBR ? 1 : 0); CeltMode celtMode = encoders[num2].GetCeltMode(); int c = layout.nb_streams + layout.nb_coupled_streams; int lookahead = encoders[num2].Lookahead; lookahead -= sampleRate / 400; int num4 = CodecHelpers.compute_frame_size(pcm, analysis_frame_size, variable_duration, c, sampleRate, bitrate_bps, lookahead, downmix, subframe_mem, encoders[num2].analysis.enabled); if (400 * num4 < sampleRate) { return -1; } if (400 * num4 != sampleRate && 200 * num4 != sampleRate && 100 * num4 != sampleRate && 50 * num4 != sampleRate && 25 * num4 != sampleRate && 50 * num4 != 3 * sampleRate) { return -1; } int num5 = layout.nb_streams * 2 - 1; if (max_data_bytes < num5) { return -2; } short[] array5 = new short[2 * num4]; int[] array6 = new int[21 * layout.nb_channels]; if (surround != 0) { surround_analysis(celtMode, pcm, array6, mem, array4, num4, 120, layout.nb_channels, sampleRate, copy_channel_in); } int num6 = surround_rate_allocation(array2, num4); if (num3 == 0) { if (bitrate_bps == -1000) { max_data_bytes = Inlines.IMIN(max_data_bytes, 3 * num6 / (24 * sampleRate / num4)); } else if (bitrate_bps != -1) { max_data_bytes = Inlines.IMIN(max_data_bytes, Inlines.IMAX(num5, 3 * bitrate_bps / (24 * sampleRate / num4))); } } for (int i = 0; i < layout.nb_streams; i++) { OpusEncoder opusEncoder = encoders[num2]; num2++; opusEncoder.Bitrate = array2[i]; if (surround != 0) { int num7 = bitrate_bps; if (num4 * 50 < sampleRate) { num7 -= 60 * (sampleRate / num4 - 50) * layout.nb_channels; } if (num7 > 10000 * layout.nb_channels) { opusEncoder.Bandwidth = OpusBandwidth.OPUS_BANDWIDTH_FULLBAND; } else if (num7 > 7000 * layout.nb_channels) { opusEncoder.Bandwidth = OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND; } else if (num7 > 5000 * layout.nb_channels) { opusEncoder.Bandwidth = OpusBandwidth.OPUS_BANDWIDTH_WIDEBAND; } else { opusEncoder.Bandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } if (i < layout.nb_coupled_streams) { opusEncoder.ForceMode = OpusMode.MODE_CELT_ONLY; opusEncoder.ForceChannels = 2; } } } num2 = 0; int num8 = 0; for (int i = 0; i < layout.nb_streams; i++) { opusRepacketizer.Reset(); OpusEncoder opusEncoder2 = encoders[num2]; int c2; int c3; if (i < layout.nb_coupled_streams) { int num9 = OpusMultistream.get_left_channel(layout, i, -1); int num10 = OpusMultistream.get_right_channel(layout, i, -1); copy_channel_in(array5, 0, 2, pcm, layout.nb_channels, num9, num4); copy_channel_in(array5, 1, 2, pcm, layout.nb_channels, num10, num4); num2++; if (surround != 0) { for (int j = 0; j < 21; j++) { array3[j] = array6[21 * num9 + j]; array3[21 + j] = array6[21 * num10 + j]; } } c2 = num9; c3 = num10; } else { int num11 = OpusMultistream.get_mono_channel(layout, i, -1); copy_channel_in(array5, 0, 1, pcm, layout.nb_channels, num11, num4); num2++; if (surround != 0) { for (int k = 0; k < 21; k++) { array3[k] = array6[21 * num11 + k]; } } c2 = num11; c3 = -1; } if (surround != 0) { opusEncoder2.SetEnergyMask(array3); } int num12 = max_data_bytes - num8; num12 -= Inlines.IMAX(0, 2 * (layout.nb_streams - i - 1) - 1); num12 = Inlines.IMIN(num12, 3832); if (i != layout.nb_streams - 1) { num12 -= ((num12 <= 253) ? 1 : 2); } if (num3 == 0 && i == layout.nb_streams - 1) { opusEncoder2.Bitrate = num12 * (8 * sampleRate / num4); } int num13 = opusEncoder2.opus_encode_native(array5, 0, num4, array, 0, num12, lsb_depth, pcm, analysis_frame_size, c2, c3, layout.nb_channels, downmix, float_api); if (num13 < 0) { return num13; } opusRepacketizer.AddPacket(array, 0, num13); num13 = opusRepacketizer.opus_repacketizer_out_range_impl(0, opusRepacketizer.GetNumFrames(), data, num, max_data_bytes - num8, (i != layout.nb_streams - 1) ? 1 : 0, (num3 == 0 && i == layout.nb_streams - 1) ? 1 : 0); num += num13; num8 += num13; } return num8; } internal static void opus_copy_channel_in_float(Span dst, int dst_offset, int dst_stride, ReadOnlySpan src, int src_stride, int src_channel, int frame_size) { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_offset] = Inlines.FLOAT2INT16(src[i * src_stride + src_channel]); } } internal static void opus_copy_channel_in_short(Span dst, int dst_offset, int dst_stride, ReadOnlySpan src, int src_stride, int src_channel, int frame_size) { for (int i = 0; i < frame_size; i++) { dst[i * dst_stride + dst_offset] = src[i * src_stride + src_channel]; } } [Obsolete("Use Span<> overrides if possible")] public int EncodeMultistream(short[] pcm, int pcm_offset, int frame_size, byte[] outputBuffer, int outputBuffer_offset, int max_data_bytes) { return EncodeMultistream(MemoryExtensions.AsSpan(pcm, pcm_offset), frame_size, MemoryExtensions.AsSpan(outputBuffer, outputBuffer_offset), max_data_bytes); } public int EncodeMultistream(ReadOnlySpan pcm, int frame_size, Span outputBuffer, int max_data_bytes) { int num = opus_multistream_encode_native(opus_copy_channel_in_short, pcm, frame_size, outputBuffer, max_data_bytes, 16, Downmix.downmix_int, 0); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG while encoding"); } throw new OpusException("An error occurred during encoding: " + CodecHelpers.opus_strerror(num), num); } return num; } [Obsolete("Use Span<> overrides if possible")] public int EncodeMultistream(float[] pcm, int pcm_offset, int frame_size, byte[] outputBuffer, int outputBuffer_offset, int max_data_bytes) { return EncodeMultistream(MemoryExtensions.AsSpan(pcm, pcm_offset), frame_size, MemoryExtensions.AsSpan(outputBuffer, outputBuffer_offset), max_data_bytes); } public int EncodeMultistream(ReadOnlySpan pcm, int frame_size, Span outputBuffer, int max_data_bytes) { int num = opus_multistream_encode_native(opus_copy_channel_in_float, pcm, frame_size, outputBuffer, max_data_bytes, 16, Downmix.downmix_float, 1); if (num < 0) { if (num == -1) { throw new ArgumentException("OPUS_BAD_ARG while encoding"); } throw new OpusException("An error occurred during encoding: " + CodecHelpers.opus_strerror(num), num); } return num; } public OpusEncoder GetMultistreamEncoderState(int streamId) { if (streamId >= layout.nb_streams) { throw new ArgumentException("Requested stream doesn't exist"); } return encoders[streamId]; } public string GetVersionString() { return CodecHelpers.GetVersionString(); } public void Dispose() { } } internal class OpusPacketInfo { public byte TOCByte { get; private set; } public IList Frames { get; private set; } public int PayloadOffset { get; private set; } public OpusBandwidth Bandwidth { get { OpusBandwidth opusBandwidth; if ((TOCByte & 0x80) == 0) { opusBandwidth = (((TOCByte & 0x60) != 96) ? ((OpusBandwidth)(1101 + ((TOCByte >> 5) & 3))) : (((TOCByte & 0x10) != 0) ? OpusBandwidth.OPUS_BANDWIDTH_FULLBAND : OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND)); } else { opusBandwidth = (OpusBandwidth)(1102 + ((TOCByte >> 5) & 3)); if (opusBandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { opusBandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } } return opusBandwidth; } } public int NumEncodedChannels { get { if ((TOCByte & 4) == 0) { return 1; } return 2; } } public OpusMode EncoderMode { get { if ((TOCByte & 0x80) != 0) { return OpusMode.MODE_CELT_ONLY; } if ((TOCByte & 0x60) == 96) { return OpusMode.MODE_HYBRID; } return OpusMode.MODE_SILK_ONLY; } } private OpusPacketInfo(byte toc, IList frames, int payloadOffset) { TOCByte = toc; Frames = frames; PayloadOffset = payloadOffset; } [Obsolete("Use Span<> overrides if possible")] public static OpusPacketInfo ParseOpusPacket(byte[] packet, int packet_offset, int len) { return ParseOpusPacket(MemoryExtensions.AsSpan(packet, packet_offset, len)); } public static OpusPacketInfo ParseOpusPacket(ReadOnlySpan packet) { int numFrames = GetNumFrames(packet); byte[][] array = new byte[numFrames][]; int[] array2 = new int[numFrames]; short[] array3 = new short[numFrames]; byte out_toc; int payload_offset; int packet_offset; int num = opus_packet_parse_impl(packet, 0, packet.Length, 0, out out_toc, array, array2, 0, array3, 0, out payload_offset, out packet_offset); if (num < 0) { throw new OpusException("An error occurred while parsing the packet", num); } IList list = new List(); for (int i = 0; i < numFrames; i++) { byte[] array4 = new byte[array3[i]]; MemoryExtensions.AsSpan(array[i], array2[i], array4.Length).CopyTo(array4); list.Add(array4); } return new OpusPacketInfo(out_toc, list, payload_offset); } public int NumSamplesPerFrame(int Fs) { int num; if ((TOCByte & 0x80) != 0) { num = (TOCByte >> 3) & 3; return (Fs << num) / 400; } if ((TOCByte & 0x60) == 96) { return ((TOCByte & 8) != 0) ? (Fs / 50) : (Fs / 100); } num = (TOCByte >> 3) & 3; if (num == 3) { return Fs * 60 / 1000; } return (Fs << num) / 100; } public static int GetNumSamplesPerFrame(ReadOnlySpan packet, int Fs) { int num; if ((packet[0] & 0x80) != 0) { num = (packet[0] >> 3) & 3; return (Fs << num) / 400; } if ((packet[0] & 0x60) == 96) { return ((packet[0] & 8) != 0) ? (Fs / 50) : (Fs / 100); } num = (packet[0] >> 3) & 3; if (num == 3) { return Fs * 60 / 1000; } return (Fs << num) / 100; } public static OpusBandwidth GetBandwidth(ReadOnlySpan packet) { OpusBandwidth opusBandwidth; if ((packet[0] & 0x80) == 0) { opusBandwidth = (((packet[0] & 0x60) != 96) ? ((OpusBandwidth)(1101 + ((packet[0] >> 5) & 3))) : (((packet[0] & 0x10) != 0) ? OpusBandwidth.OPUS_BANDWIDTH_FULLBAND : OpusBandwidth.OPUS_BANDWIDTH_SUPERWIDEBAND)); } else { opusBandwidth = (OpusBandwidth)(1102 + ((packet[0] >> 5) & 3)); if (opusBandwidth == OpusBandwidth.OPUS_BANDWIDTH_MEDIUMBAND) { opusBandwidth = OpusBandwidth.OPUS_BANDWIDTH_NARROWBAND; } } return opusBandwidth; } public static int GetNumEncodedChannels(ReadOnlySpan packet) { if ((packet[0] & 4) == 0) { return 1; } return 2; } public static int GetNumFrames(ReadOnlySpan packet) { if (packet.Length < 1) { return -1; } switch (packet[0] & 3) { case 0: return 1; default: return 2; case 3: if (packet.Length < 2) { return -4; } return packet[1] & 0x3F; } } public static int GetNumSamples(ReadOnlySpan packet, int Fs) { int numFrames = GetNumFrames(packet); if (numFrames < 0) { return numFrames; } int num = numFrames * GetNumSamplesPerFrame(packet, Fs); if (num * 25 > Fs * 3) { return -4; } return num; } [Obsolete("Use Span<> overrides if possible")] public static int GetNumSamples(OpusDecoder dec, byte[] packet, int packet_offset, int len) { return GetNumSamples(MemoryExtensions.AsSpan(packet, packet_offset, len), dec.Fs); } public static int GetNumSamples(OpusDecoder dec, ReadOnlySpan packet) { return GetNumSamples(packet, dec.Fs); } public static OpusMode GetEncoderMode(ReadOnlySpan packet) { if ((packet[0] & 0x80) != 0) { return OpusMode.MODE_CELT_ONLY; } if ((packet[0] & 0x60) == 96) { return OpusMode.MODE_HYBRID; } return OpusMode.MODE_SILK_ONLY; } internal static int encode_size(int size, Span data, int data_ptr) { if (size < 252) { data[data_ptr] = (byte)size; return 1; } data[data_ptr] = (byte)(252 + (size & 3)); data[data_ptr + 1] = (byte)(size - data[data_ptr] >> 2); return 2; } internal static int parse_size(ReadOnlySpan data, int data_ptr, int len, BoxedValueShort size) { if (len < 1) { size.Val = -1; return -1; } if (data[data_ptr] < 252) { size.Val = data[data_ptr]; return 1; } if (len < 2) { size.Val = -1; return -1; } size.Val = (short)(4 * data[data_ptr + 1] + data[data_ptr]); return 2; } internal static int opus_packet_parse_impl(ReadOnlySpan data, int data_ptr, int len, int self_delimited, out byte out_toc, byte[][] frames, Span frames_ptrs, int frames_ptr, Span sizes, int sizes_ptr, out int payload_offset, out int packet_offset) { int num = 0; int num2 = data_ptr; out_toc = 0; payload_offset = 0; packet_offset = 0; if (sizes.IsEmpty || len < 0) { return -1; } if (len == 0) { return -4; } int numSamplesPerFrame = GetNumSamplesPerFrame(data.Slice(data_ptr), 48000); int num3 = 0; byte b = data[data_ptr++]; len--; int num4 = len; int num5; switch (b & 3) { case 0: num5 = 1; break; case 1: num5 = 2; num3 = 1; if (self_delimited == 0) { if ((len & 1) != 0) { return -4; } num4 = len / 2; sizes[sizes_ptr] = (short)num4; } break; case 2: { num5 = 2; BoxedValueShort boxedValueShort = new BoxedValueShort(sizes[sizes_ptr]); int num8 = parse_size(data, data_ptr, len, boxedValueShort); sizes[sizes_ptr] = boxedValueShort.Val; len -= num8; if (sizes[sizes_ptr] < 0 || sizes[sizes_ptr] > len) { return -4; } data_ptr += num8; num4 = len - sizes[sizes_ptr]; break; } default: { if (len < 1) { return -4; } byte b2 = data[data_ptr++]; num5 = b2 & 0x3F; if (num5 <= 0 || numSamplesPerFrame * num5 > 5760) { return -4; } len--; if ((b2 & 0x40) != 0) { int num6; do { if (len <= 0) { return -4; } num6 = data[data_ptr++]; len--; int num7 = ((num6 == 255) ? 254 : num6); len -= num7; num += num7; } while (num6 == 255); } if (len < 0) { return -4; } num3 = (((b2 & 0x80) == 0) ? 1 : 0); if (num3 == 0) { num4 = len; for (int i = 0; i < num5 - 1; i++) { BoxedValueShort boxedValueShort = new BoxedValueShort(sizes[sizes_ptr + i]); int num8 = parse_size(data, data_ptr, len, boxedValueShort); sizes[sizes_ptr + i] = boxedValueShort.Val; len -= num8; if (sizes[sizes_ptr + i] < 0 || sizes[sizes_ptr + i] > len) { return -4; } data_ptr += num8; num4 -= num8 + sizes[sizes_ptr + i]; } if (num4 < 0) { return -4; } } else if (self_delimited == 0) { num4 = len / num5; if (num4 * num5 != len) { return -4; } for (int i = 0; i < num5 - 1; i++) { sizes[sizes_ptr + i] = (short)num4; } } break; } } if (self_delimited != 0) { BoxedValueShort boxedValueShort2 = new BoxedValueShort(sizes[sizes_ptr + num5 - 1]); int num8 = parse_size(data, data_ptr, len, boxedValueShort2); sizes[sizes_ptr + num5 - 1] = boxedValueShort2.Val; len -= num8; if (sizes[sizes_ptr + num5 - 1] < 0 || sizes[sizes_ptr + num5 - 1] > len) { return -4; } data_ptr += num8; if (num3 != 0) { if (sizes[sizes_ptr + num5 - 1] * num5 > len) { return -4; } for (int i = 0; i < num5 - 1; i++) { sizes[sizes_ptr + i] = sizes[sizes_ptr + num5 - 1]; } } else if (num8 + sizes[sizes_ptr + num5 - 1] > num4) { return -4; } } else { if (num4 > 1275) { return -4; } sizes[sizes_ptr + num5 - 1] = (short)num4; } payload_offset = data_ptr - num2; for (int i = 0; i < num5; i++) { if (frames != null) { byte[] array = new byte[data.Length]; data.CopyTo(MemoryExtensions.AsSpan(array)); frames[frames_ptr + i] = array; } if (!frames_ptrs.IsEmpty) { frames_ptrs[frames_ptr + i] = data_ptr; } data_ptr += sizes[sizes_ptr + i]; } packet_offset = num + (data_ptr - num2); out_toc = b; return num5; } } internal class OpusRepacketizer { internal byte toc; internal int nb_frames; internal readonly byte[][] frames = new byte[48][]; internal readonly int[] frames_ptrs = new int[48]; internal readonly short[] len = new short[48]; internal int framesize; public void Reset() { nb_frames = 0; } public OpusRepacketizer() { Reset(); } internal int opus_repacketizer_cat_impl(Span data, int data_ptr, int len, int self_delimited) { if (len < 1) { return -4; } if (nb_frames == 0) { toc = data[data_ptr]; framesize = OpusPacketInfo.GetNumSamplesPerFrame(data.Slice(data_ptr), 8000); } else if ((toc & 0xFC) != (data[data_ptr] & 0xFC)) { return -4; } int numFrames = OpusPacketInfo.GetNumFrames(data.Slice(data_ptr, len)); if (numFrames < 1) { return -4; } if ((numFrames + nb_frames) * framesize > 960) { return -4; } byte out_toc; int payload_offset; int num = OpusPacketInfo.opus_packet_parse_impl(data, data_ptr, len, self_delimited, out out_toc, frames, frames_ptrs, nb_frames, this.len, nb_frames, out payload_offset, out payload_offset); if (num < 1) { return num; } nb_frames += numFrames; return 0; } public int AddPacket(Span data, int data_offset, int len) { return opus_repacketizer_cat_impl(data, data_offset, len, 0); } public int GetNumFrames() { return nb_frames; } internal int opus_repacketizer_out_range_impl(int begin, int end, Span data, int data_ptr, int maxlen, int self_delimited, int pad) { if (begin < 0 || begin >= end || end > nb_frames) { return -1; } int num = end - begin; int num2 = ((self_delimited != 0) ? (1 + ((len[num - 1] >= 252) ? 1 : 0)) : 0); int num3 = data_ptr; switch (num) { case 1: num2 += len[0] + 1; if (num2 > maxlen) { return -2; } data[num3++] = (byte)(toc & 0xFC); break; case 2: if (len[1] == len[0]) { num2 += 2 * len[0] + 1; if (num2 > maxlen) { return -2; } data[num3++] = (byte)((toc & 0xFC) | 1); break; } num2 += len[0] + len[1] + 2 + ((len[0] >= 252) ? 1 : 0); if (num2 > maxlen) { return -2; } data[num3++] = (byte)((toc & 0xFC) | 2); num3 += OpusPacketInfo.encode_size(len[0], data, num3); break; } if (num > 2 || (pad != 0 && num2 < maxlen)) { int num4 = 0; num3 = data_ptr; num2 = ((self_delimited != 0) ? (1 + ((len[num - 1] >= 252) ? 1 : 0)) : 0); int num5 = 0; for (int i = 1; i < num; i++) { if (len[i] != len[0]) { num5 = 1; break; } } if (num5 != 0) { num2 += 2; for (int i = 0; i < num - 1; i++) { num2 += 1 + ((len[i] >= 252) ? 1 : 0) + len[i]; } num2 += len[num - 1]; if (num2 > maxlen) { return -2; } data[num3++] = (byte)((toc & 0xFC) | 3); data[num3++] = (byte)(num | 0x80); } else { num2 += num * len[0] + 2; if (num2 > maxlen) { return -2; } data[num3++] = (byte)((toc & 0xFC) | 3); data[num3++] = (byte)num; } num4 = ((pad != 0) ? (maxlen - num2) : 0); if (num4 != 0) { data[data_ptr + 1] |= 64; int num6 = (num4 - 1) / 255; for (int i = 0; i < num6; i++) { data[num3++] = byte.MaxValue; } data[num3++] = (byte)(num4 - 255 * num6 - 1); num2 += num4; } if (num5 != 0) { for (int i = 0; i < num - 1; i++) { num3 += OpusPacketInfo.encode_size(len[i], data, num3); } } } if (self_delimited != 0) { int num7 = OpusPacketInfo.encode_size(len[num - 1], data, num3); num3 += num7; } for (int i = begin; i < num + begin; i++) { MemoryExtensions.AsSpan(frames[i], frames_ptrs[i], len[i]).CopyTo(data.Slice(num3)); num3 += len[i]; } if (pad != 0) { while (num3 < data_ptr + maxlen) { data[num3++] = 0; } } return num2; } public int CreatePacket(int begin, int end, byte[] data, int data_offset, int maxlen) { return opus_repacketizer_out_range_impl(begin, end, data, data_offset, maxlen, 0, 0); } public int CreatePacket(byte[] data, int data_offset, int maxlen) { return opus_repacketizer_out_range_impl(0, nb_frames, data, data_offset, maxlen, 0, 0); } public static int PadPacket(Span data, int data_offset, int len, int new_len) { OpusRepacketizer opusRepacketizer = new OpusRepacketizer(); if (len < 1) { return -1; } if (len == new_len) { return 0; } if (len > new_len) { return -1; } opusRepacketizer.Reset(); Arrays.MemMoveByte(data, data_offset, data_offset + new_len - len, len); opusRepacketizer.AddPacket(data, data_offset + new_len - len, len); int num = opusRepacketizer.opus_repacketizer_out_range_impl(0, opusRepacketizer.nb_frames, data, data_offset, new_len, 0, 1); if (num > 0) { return 0; } return num; } public static int UnpadPacket(byte[] data, int data_offset, int len) { if (len < 1) { return -1; } OpusRepacketizer opusRepacketizer = new OpusRepacketizer(); opusRepacketizer.Reset(); int num = opusRepacketizer.AddPacket(data, data_offset, len); if (num < 0) { return num; } return opusRepacketizer.opus_repacketizer_out_range_impl(0, opusRepacketizer.nb_frames, data, data_offset, len, 0, 0); } public static int PadMultistreamPacket(byte[] data, int data_offset, int len, int new_len, int nb_streams) { short[] array = new short[48]; if (len < 1) { return -1; } if (len == new_len) { return 0; } if (len > new_len) { return -1; } int num = new_len - len; for (int i = 0; i < nb_streams - 1; i++) { if (len <= 0) { return -4; } byte out_toc; int payload_offset; int packet_offset; int num2 = OpusPacketInfo.opus_packet_parse_impl(data, data_offset, len, 1, out out_toc, null, null, 0, array, 0, out payload_offset, out packet_offset); if (num2 < 0) { return num2; } data_offset += packet_offset; len -= packet_offset; } return PadPacket(data, data_offset, len, len + num); } public static int UnpadMultistreamPacket(byte[] data, int data_offset, int len, int nb_streams) { short[] array = new short[48]; OpusRepacketizer opusRepacketizer = new OpusRepacketizer(); if (len < 1) { return -1; } int num = data_offset; int num2 = 0; for (int i = 0; i < nb_streams; i++) { int self_delimited = ((i != nb_streams) ? 1 : 0) - 1; if (len <= 0) { return -4; } opusRepacketizer.Reset(); int num3 = OpusPacketInfo.opus_packet_parse_impl(data, data_offset, len, self_delimited, out var _, null, null, 0, array, 0, out var _, out var packet_offset); if (num3 < 0) { return num3; } num3 = opusRepacketizer.opus_repacketizer_cat_impl(data, data_offset, packet_offset, self_delimited); if (num3 < 0) { return num3; } num3 = opusRepacketizer.opus_repacketizer_out_range_impl(0, opusRepacketizer.nb_frames, data, num, len, self_delimited, 0); if (num3 < 0) { return num3; } num2 += num3; num += num3; data_offset += packet_offset; len -= packet_offset; } return num2; } } internal class StereoWidthState { internal int XX; internal int XY; internal int YY; internal int smoothed_width; internal int max_follower; internal void Reset() { XX = 0; XY = 0; YY = 0; smoothed_width = 0; max_follower = 0; } } internal class TonalityAnalysisState { internal bool enabled; internal readonly float[] angle = new float[240]; internal readonly float[] d_angle = new float[240]; internal readonly float[] d2_angle = new float[240]; internal readonly int[] inmem = new int[720]; internal int mem_fill; internal readonly float[] prev_band_tonality = new float[18]; internal float prev_tonality; internal readonly float[][] E = Arrays.InitTwoDimensionalArray(8, 18); internal readonly float[] lowE = new float[18]; internal readonly float[] highE = new float[18]; internal readonly float[] meanE = new float[21]; internal readonly float[] mem = new float[32]; internal readonly float[] cmean = new float[8]; internal readonly float[] std = new float[9]; internal float music_prob; internal float Etracker; internal float lowECount; internal int E_count; internal int last_music; internal int last_transition; internal int count; internal readonly float[] subframe_mem = new float[3]; internal int analysis_offset; internal readonly float[] pspeech = new float[200]; internal readonly float[] pmusic = new float[200]; internal float speech_confidence; internal float music_confidence; internal int speech_confidence_count; internal int music_confidence_count; internal int write_pos; internal int read_pos; internal int read_subframe; internal readonly AnalysisInfo[] info = new AnalysisInfo[200]; internal TonalityAnalysisState() { for (int i = 0; i < 200; i++) { info[i] = new AnalysisInfo(); } } internal void Reset() { Arrays.MemSetFloat(angle, 0f, 240); Arrays.MemSetFloat(d_angle, 0f, 240); Arrays.MemSetFloat(d2_angle, 0f, 240); Arrays.MemSetInt(inmem, 0, 720); mem_fill = 0; Arrays.MemSetFloat(prev_band_tonality, 0f, 18); prev_tonality = 0f; for (int i = 0; i < 8; i++) { Arrays.MemSetFloat(E[i], 0f, 18); } Arrays.MemSetFloat(lowE, 0f, 18); Arrays.MemSetFloat(highE, 0f, 18); Arrays.MemSetFloat(meanE, 0f, 21); Arrays.MemSetFloat(mem, 0f, 32); Arrays.MemSetFloat(cmean, 0f, 8); Arrays.MemSetFloat(std, 0f, 9); music_prob = 0f; Etracker = 0f; lowECount = 0f; E_count = 0; last_music = 0; last_transition = 0; count = 0; Arrays.MemSetFloat(subframe_mem, 0f, 3); analysis_offset = 0; Arrays.MemSetFloat(pspeech, 0f, 200); Arrays.MemSetFloat(pmusic, 0f, 200); speech_confidence = 0f; music_confidence = 0f; speech_confidence_count = 0; music_confidence_count = 0; write_pos = 0; read_pos = 0; read_subframe = 0; for (int j = 0; j < 200; j++) { info[j].Reset(); } } } internal class VorbisLayout { internal int nb_streams; internal int nb_coupled_streams; internal byte[] mapping; internal static readonly VorbisLayout[] vorbis_mappings = new VorbisLayout[8] { new VorbisLayout(1, 0, new byte[1]), new VorbisLayout(1, 1, new byte[2] { 0, 1 }), new VorbisLayout(2, 1, new byte[3] { 0, 2, 1 }), new VorbisLayout(2, 2, new byte[4] { 0, 1, 2, 3 }), new VorbisLayout(3, 2, new byte[5] { 0, 4, 1, 2, 3 }), new VorbisLayout(4, 2, new byte[6] { 0, 4, 1, 2, 3, 5 }), new VorbisLayout(4, 3, new byte[7] { 0, 4, 1, 2, 3, 5, 6 }), new VorbisLayout(5, 3, new byte[8] { 0, 6, 1, 2, 3, 4, 5, 7 }) }; internal VorbisLayout(int streams, int coupled_streams, byte[] map) { nb_streams = streams; nb_coupled_streams = coupled_streams; mapping = map; } } } namespace Concentus.Enums { internal enum OpusApplication { OPUS_APPLICATION_UNIMPLEMENTED = 0, OPUS_APPLICATION_VOIP = 2048, OPUS_APPLICATION_AUDIO = 2049, OPUS_APPLICATION_RESTRICTED_LOWDELAY = 2051 } internal enum OpusBandwidth { OPUS_BANDWIDTH_AUTO = -1000, OPUS_BANDWIDTH_NARROWBAND = 1101, OPUS_BANDWIDTH_MEDIUMBAND = 1102, OPUS_BANDWIDTH_WIDEBAND = 1103, OPUS_BANDWIDTH_SUPERWIDEBAND = 1104, OPUS_BANDWIDTH_FULLBAND = 1105 } internal static class OpusBandwidthHelpers { public static int GetOrdinal(OpusBandwidth bw) { return (int)(bw - 1101); } public static OpusBandwidth MIN(OpusBandwidth a, OpusBandwidth b) { if (a < b) { return a; } return b; } public static OpusBandwidth MAX(OpusBandwidth a, OpusBandwidth b) { if (a > b) { return a; } return b; } } internal static class OpusControl { internal const int OPUS_SET_APPLICATION_REQUEST = 4000; internal const int OPUS_GET_APPLICATION_REQUEST = 4001; internal const int OPUS_SET_BITRATE_REQUEST = 4002; internal const int OPUS_GET_BITRATE_REQUEST = 4003; internal const int OPUS_SET_MAX_BANDWIDTH_REQUEST = 4004; internal const int OPUS_GET_MAX_BANDWIDTH_REQUEST = 4005; internal const int OPUS_SET_VBR_REQUEST = 4006; internal const int OPUS_GET_VBR_REQUEST = 4007; internal const int OPUS_SET_BANDWIDTH_REQUEST = 4008; internal const int OPUS_GET_BANDWIDTH_REQUEST = 4009; internal const int OPUS_SET_COMPLEXITY_REQUEST = 4010; internal const int OPUS_GET_COMPLEXITY_REQUEST = 4011; internal const int OPUS_SET_INBAND_FEC_REQUEST = 4012; internal const int OPUS_GET_INBAND_FEC_REQUEST = 4013; internal const int OPUS_SET_PACKET_LOSS_PERC_REQUEST = 4014; internal const int OPUS_GET_PACKET_LOSS_PERC_REQUEST = 4015; internal const int OPUS_SET_DTX_REQUEST = 4016; internal const int OPUS_GET_DTX_REQUEST = 4017; internal const int OPUS_SET_VBR_CONSTRAINT_REQUEST = 4020; internal const int OPUS_GET_VBR_CONSTRAINT_REQUEST = 4021; internal const int OPUS_SET_FORCE_CHANNELS_REQUEST = 4022; internal const int OPUS_GET_FORCE_CHANNELS_REQUEST = 4023; internal const int OPUS_SET_SIGNAL_REQUEST = 4024; internal const int OPUS_GET_SIGNAL_REQUEST = 4025; internal const int OPUS_GET_LOOKAHEAD_REQUEST = 4027; internal const int OPUS_GET_SAMPLE_RATE_REQUEST = 4029; internal const int OPUS_GET_FINAL_RANGE_REQUEST = 4031; internal const int OPUS_GET_PITCH_REQUEST = 4033; internal const int OPUS_SET_GAIN_REQUEST = 4034; internal const int OPUS_GET_GAIN_REQUEST = 4045; internal const int OPUS_SET_LSB_DEPTH_REQUEST = 4036; internal const int OPUS_GET_LSB_DEPTH_REQUEST = 4037; internal const int OPUS_GET_LAST_PACKET_DURATION_REQUEST = 4039; internal const int OPUS_SET_EXPERT_FRAME_DURATION_REQUEST = 4040; internal const int OPUS_GET_EXPERT_FRAME_DURATION_REQUEST = 4041; internal const int OPUS_SET_PREDICTION_DISABLED_REQUEST = 4042; internal const int OPUS_GET_PREDICTION_DISABLED_REQUEST = 4043; internal const int OPUS_RESET_STATE = 4028; internal const int OPUS_SET_VOICE_RATIO_REQUEST = 11018; internal const int OPUS_GET_VOICE_RATIO_REQUEST = 11019; internal const int OPUS_SET_FORCE_MODE_REQUEST = 11002; } internal static class OpusError { public const int OPUS_OK = 0; public const int OPUS_BAD_ARG = -1; public const int OPUS_BUFFER_TOO_SMALL = -2; public const int OPUS_INTERNAL_ERROR = -3; public const int OPUS_INVALID_PACKET = -4; public const int OPUS_UNIMPLEMENTED = -5; public const int OPUS_INVALID_STATE = -6; public const int OPUS_ALLOC_FAIL = -7; public const int CONCENTUS_UNKNOWN_ERROR = -100; } internal enum OpusFramesize { OPUS_FRAMESIZE_ARG = 5000, OPUS_FRAMESIZE_2_5_MS = 5001, OPUS_FRAMESIZE_5_MS = 5002, OPUS_FRAMESIZE_10_MS = 5003, OPUS_FRAMESIZE_20_MS = 5004, OPUS_FRAMESIZE_40_MS = 5005, OPUS_FRAMESIZE_60_MS = 5006, OPUS_FRAMESIZE_VARIABLE = 5010 } internal enum OpusMode { MODE_AUTO = -1000, MODE_SILK_ONLY = 1000, MODE_HYBRID = 1001, MODE_CELT_ONLY = 1002 } internal enum OpusSignal { OPUS_SIGNAL_AUTO = -1000, OPUS_SIGNAL_VOICE = 3001, OPUS_SIGNAL_MUSIC = 3002 } } namespace Concentus.Native { internal class KernelInteropLinux { private interface ILibDl { IntPtr DLOpen(string fileName, int flags); int DLClose(IntPtr handle); IntPtr DLError(); } private class LibDL : ILibDl { public IntPtr DLOpen(string fileName, int flags) { return dlopen(fileName, flags); } public int DLClose(IntPtr handle) { return dlclose(handle); } public IntPtr DLError() { return dlerror(); } [DllImport("libdl.so")] private static extern IntPtr dlopen(string fileName, int flags); [DllImport("libdl.so")] private static extern int dlclose(IntPtr handle); [DllImport("libdl.so")] private static extern IntPtr dlerror(); } private class LibDL2 : ILibDl { public IntPtr DLOpen(string fileName, int flags) { return dlopen(fileName, flags); } public int DLClose(IntPtr handle) { return dlclose(handle); } public IntPtr DLError() { return dlerror(); } [DllImport("libdl.so.2")] private static extern IntPtr dlopen(string fileName, int flags); [DllImport("libdl.so.2")] private static extern int dlclose(IntPtr handle); [DllImport("libdl.so.2")] private static extern IntPtr dlerror(); } internal const int RTLD_NOW = 2; private static Lazy _libDlImpl = new Lazy(GetLibDL, LazyThreadSafetyMode.ExecutionAndPublication); internal static readonly IReadOnlyDictionary POSSIBLE_UNIX_MACHINES = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "amd64", PlatformArchitecture.X64 }, { "x86_64", PlatformArchitecture.X64 }, { "i686-64", PlatformArchitecture.X64 }, { "x86", PlatformArchitecture.I386 }, { "i686", PlatformArchitecture.I386 }, { "i686-AT386", PlatformArchitecture.I386 }, { "i386", PlatformArchitecture.I386 }, { "x86pc", PlatformArchitecture.I386 }, { "i86pc", PlatformArchitecture.I386 }, { "armv6l", PlatformArchitecture.ArmV6 }, { "armv7l", PlatformArchitecture.ArmV7 }, { "arm64", PlatformArchitecture.Arm64 }, { "aarch64", PlatformArchitecture.Arm64 }, { "aarch64_be", PlatformArchitecture.Arm64 }, { "armv8l", PlatformArchitecture.Arm64 }, { "armv8b", PlatformArchitecture.Arm64 }, { "mips64", PlatformArchitecture.Mips64 }, { "ppc64", PlatformArchitecture.PowerPC64 }, { "ppc64le", PlatformArchitecture.PowerPC64 } }; private static ILibDl GetLibDL() { try { LibDL libDL = new LibDL(); libDL.DLError(); return libDL; } catch (Exception) { return new LibDL2(); } } public static IntPtr dlopen(string fileName, int flags) { return _libDlImpl.Value.DLOpen(fileName, flags); } public static int dlclose(IntPtr handle) { return _libDlImpl.Value.DLClose(handle); } public static IntPtr dlerror() { return _libDlImpl.Value.DLError(); } internal static PlatformArchitecture? TryGetArchForUnix(TextWriter logger) { try { logger?.WriteLine("Running uname to determine system info..."); using Process process = Process.Start(new ProcessStartInfo { FileName = "uname", Arguments = "-m", UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }); using StreamReader streamReader = process.StandardOutput; string text = streamReader.ReadToEnd(); if (string.IsNullOrEmpty(text)) { return null; } text = text.Trim(); if (POSSIBLE_UNIX_MACHINES.TryGetValue(text, out var value)) { logger?.WriteLine("Got architecture from uname: " + text); return value; } } catch (Exception value2) { logger?.WriteLine(value2); } return null; } } internal class KernelInteropMacOS { internal const int RTLD_NOW = 2; [DllImport("libSystem.dylib")] internal static extern IntPtr dlopen(string fileName, int flags); [DllImport("libSystem.dylib")] internal static extern int dlclose(IntPtr handle); [DllImport("libSystem.dylib")] internal static extern IntPtr dlerror(); } internal class KernelInteropWindows { internal struct SYSTEM_INFO { internal ushort wProcessorArchitecture; internal ushort wReserved; internal uint dwPageSize; internal IntPtr lpMinimumApplicationAddress; internal IntPtr lpMaximumApplicationAddress; internal IntPtr dwActiveProcessorMask; internal uint dwNumberOfProcessors; internal uint dwProcessorType; internal uint dwAllocationGranularity; internal ushort wProcessorLevel; internal ushort wProcessorRevision; } internal const uint LOAD_LIBRARY_AS_DATAFILE = 2u; internal const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 4096u; internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0; internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9; internal const ushort PROCESSOR_ARCHITECTURE_ARM = 5; internal const ushort PROCESSOR_ARCHITECTURE_ARM64 = 18; internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6; internal const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = ushort.MaxValue; [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern IntPtr LoadLibraryExW(string lpFileName, IntPtr hFile, uint dwFlags); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll")] internal static extern uint GetLastError(); [DllImport("kernel32.dll", SetLastError = true)] internal static extern void GetSystemInfo(ref SYSTEM_INFO Info); } internal enum NativeLibraryStatus { Unknown, Available, Unavailable } internal class NativeOpus { private const string LIBRARY_NAME = "opus"; internal const int OPUS_SET_APPLICATION_REQUEST = 4000; internal const int OPUS_GET_APPLICATION_REQUEST = 4001; internal const int OPUS_SET_BITRATE_REQUEST = 4002; internal const int OPUS_GET_BITRATE_REQUEST = 4003; internal const int OPUS_SET_MAX_BANDWIDTH_REQUEST = 4004; internal const int OPUS_GET_MAX_BANDWIDTH_REQUEST = 4005; internal const int OPUS_SET_VBR_REQUEST = 4006; internal const int OPUS_GET_VBR_REQUEST = 4007; internal const int OPUS_SET_BANDWIDTH_REQUEST = 4008; internal const int OPUS_GET_BANDWIDTH_REQUEST = 4009; internal const int OPUS_SET_COMPLEXITY_REQUEST = 4010; internal const int OPUS_GET_COMPLEXITY_REQUEST = 4011; internal const int OPUS_SET_INBAND_FEC_REQUEST = 4012; internal const int OPUS_GET_INBAND_FEC_REQUEST = 4013; internal const int OPUS_SET_PACKET_LOSS_PERC_REQUEST = 4014; internal const int OPUS_GET_PACKET_LOSS_PERC_REQUEST = 4015; internal const int OPUS_SET_DTX_REQUEST = 4016; internal const int OPUS_GET_DTX_REQUEST = 4017; internal const int OPUS_SET_VBR_CONSTRAINT_REQUEST = 4020; internal const int OPUS_GET_VBR_CONSTRAINT_REQUEST = 4021; internal const int OPUS_SET_FORCE_CHANNELS_REQUEST = 4022; internal const int OPUS_GET_FORCE_CHANNELS_REQUEST = 4023; internal const int OPUS_SET_SIGNAL_REQUEST = 4024; internal const int OPUS_GET_SIGNAL_REQUEST = 4025; internal const int OPUS_GET_LOOKAHEAD_REQUEST = 4027; internal const int OPUS_GET_SAMPLE_RATE_REQUEST = 4029; internal const int OPUS_GET_FINAL_RANGE_REQUEST = 4031; internal const int OPUS_GET_PITCH_REQUEST = 4033; internal const int OPUS_SET_GAIN_REQUEST = 4034; internal const int OPUS_GET_GAIN_REQUEST = 4045; internal const int OPUS_SET_LSB_DEPTH_REQUEST = 4036; internal const int OPUS_GET_LSB_DEPTH_REQUEST = 4037; internal const int OPUS_GET_LAST_PACKET_DURATION_REQUEST = 4039; internal const int OPUS_SET_EXPERT_FRAME_DURATION_REQUEST = 4040; internal const int OPUS_GET_EXPERT_FRAME_DURATION_REQUEST = 4041; internal const int OPUS_SET_PREDICTION_DISABLED_REQUEST = 4042; internal const int OPUS_GET_PREDICTION_DISABLED_REQUEST = 4043; internal const int OPUS_SET_FORCE_MODE_REQUEST = 11002; internal const int OPUS_RESET_STATE = 4028; internal static bool Initialize(TextWriter logger) { if (NativePlatformUtils.PrepareNativeLibrary("opus", logger) == NativeLibraryStatus.Available) { return opus_get_version_string() != IntPtr.Zero; } return false; } [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern NativeOpusDecoder opus_decoder_create(int Fs, int channels, out int error); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern NativeOpusMultistreamDecoder opus_multistream_decoder_create(int Fs, int channels, int streams, int coupled_streams, byte* mapping, out int error); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_decode(NativeOpusDecoder st, byte* data, int len, short* pcm, int frame_size, int decode_fec); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_decode_float(NativeOpusDecoder st, byte* data, int len, float* pcm, int frame_size, int decode_fec); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_multistream_decode(NativeOpusMultistreamDecoder st, byte* data, int len, short* pcm, int frame_size, int decode_fec); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_multistream_decode_float(NativeOpusMultistreamDecoder st, byte* data, int len, float* pcm, int frame_size, int decode_fec); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern NativeOpusEncoder opus_encoder_create(int Fs, int channels, int application, out int error); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern NativeOpusMultistreamEncoder opus_multistream_surround_encoder_create(int Fs, int channels, int mapping_family, out int streams, out int coupled_streams, byte* mapping, int application, out int error); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_encode(NativeOpusEncoder st, short* pcm, int frame_size, byte* data, int max_data_bytes); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_encode_float(NativeOpusEncoder st, float* pcm, int frame_size, byte* data, int max_data_bytes); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_multistream_encode(NativeOpusMultistreamEncoder st, short* pcm, int frame_size, byte* data, int max_data_bytes); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal unsafe static extern int opus_multistream_encode_float(NativeOpusMultistreamEncoder st, float* pcm, int frame_size, byte* data, int max_data_bytes); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_decoder_ctl(NativeOpusDecoder st, int request, int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_decoder_ctl(NativeOpusDecoder st, int request, out int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_encoder_ctl(NativeOpusEncoder st, int request, int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_encoder_ctl(NativeOpusEncoder st, int request, out int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_multistream_decoder_ctl(NativeOpusMultistreamDecoder st, int request, int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_multistream_decoder_ctl(NativeOpusMultistreamDecoder st, int request, out int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_multistream_encoder_ctl(NativeOpusMultistreamEncoder st, int request, int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern int opus_multistream_encoder_ctl(NativeOpusMultistreamEncoder st, int request, out int value); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr opus_get_version_string(); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern void opus_encoder_destroy(IntPtr encoder); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern void opus_multistream_encoder_destroy(IntPtr encoder); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern void opus_decoder_destroy(IntPtr decoder); [DllImport("opus", CallingConvention = CallingConvention.Cdecl)] internal static extern void opus_multistream_decoder_destroy(IntPtr decoder); } internal class NativeOpusDecoder : SafeHandleZeroOrMinusOneIsInvalid, IOpusDecoder, IDisposable { private int _sampleRate; private int _numChannels; private NativeOpusDecoder NativeHandle => this; public int SampleRate => _sampleRate; public int NumChannels => _numChannels; public OpusBandwidth Bandwidth { get { NativeOpus.opus_decoder_ctl(NativeHandle, 4009, out var value); return (OpusBandwidth)value; } } public uint FinalRange { get { NativeOpus.opus_decoder_ctl(NativeHandle, 4031, out var value); return (uint)value; } } public int Gain { get { NativeOpus.opus_decoder_ctl(NativeHandle, 4045, out var value); return value; } set { NativeOpus.opus_decoder_ctl(NativeHandle, 4034, value); } } public int LastPacketDuration { get { NativeOpus.opus_decoder_ctl(NativeHandle, 4039, out var value); return value; } } public int Pitch { get { NativeOpus.opus_decoder_ctl(NativeHandle, 4033, out var value); return value; } } internal NativeOpusDecoder() : base(ownsHandle: true) { } protected override bool ReleaseHandle() { NativeOpus.opus_encoder_destroy(handle); return true; } public static NativeOpusDecoder Create(int sampleRate, int channelCount) { int error; NativeOpusDecoder nativeOpusDecoder = NativeOpus.opus_decoder_create(sampleRate, channelCount, out error); if (error != 0) { nativeOpusDecoder.Dispose(); throw new Exception($"Failed to create opus decoder: error {error}"); } nativeOpusDecoder._sampleRate = sampleRate; nativeOpusDecoder._numChannels = channelCount; return nativeOpusDecoder; } public unsafe int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false) { fixed (float* pcm = out_pcm) { if (in_data.Length == 0) { return NativeOpus.opus_decode_float(NativeHandle, null, 0, pcm, frame_size, decode_fec ? 1 : 0); } fixed (byte* data = in_data) { return NativeOpus.opus_decode_float(NativeHandle, data, in_data.Length, pcm, frame_size, decode_fec ? 1 : 0); } } } public unsafe int Decode(ReadOnlySpan in_data, Span out_pcm, int frame_size, bool decode_fec = false) { fixed (short* pcm = out_pcm) { if (in_data.Length == 0) { return NativeOpus.opus_decode(NativeHandle, null, 0, pcm, frame_size, decode_fec ? 1 : 0); } fixed (byte* data = in_data) { return NativeOpus.opus_decode(NativeHandle, data, in_data.Length, pcm, frame_size, decode_fec ? 1 : 0); } } } public void ResetState() { NativeOpus.opus_decoder_ctl(NativeHandle, 4028, 0); } public string GetVersionString() { return Marshal.PtrToStringAnsi(NativeOpus.opus_get_version_string()); } } internal class NativeOpusEncoder : SafeHandleZeroOrMinusOneIsInvalid, IOpusEncoder, IDisposable { private int _sampleRate; private int _numChannels; private NativeOpusEncoder NativeHandle => this; public int SampleRate => _sampleRate; public int NumChannels => _numChannels; public int Complexity { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4011, out var value); return value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4010, value); } } public bool UseDTX { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4017, out var value); return value != 0; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4016, value ? 1 : 0); } } public int Bitrate { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4003, out var value); return value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4002, value); } } public OpusMode ForceMode { set { NativeOpus.opus_encoder_ctl(NativeHandle, 11002, (int)value); } } public bool UseVBR { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4007, out var value); return value != 0; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4006, value ? 1 : 0); } } public OpusApplication Application { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4001, out var value); return (OpusApplication)value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4000, (int)value); } } public int ForceChannels { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4023, out var value); return value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4022, value); } } public OpusBandwidth MaxBandwidth { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4005, out var value); return (OpusBandwidth)value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4004, (int)value); } } public OpusBandwidth Bandwidth { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4009, out var value); return (OpusBandwidth)value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4008, (int)value); } } public bool UseInbandFEC { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4013, out var value); return value != 0; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4012, value ? 1 : 0); } } public int PacketLossPercent { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4015, out var value); return value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4014, value); } } public bool UseConstrainedVBR { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4021, out var value); return value != 0; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4020, value ? 1 : 0); } } public OpusSignal SignalType { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4025, out var value); return (OpusSignal)value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4024, (int)value); } } public int Lookahead { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4027, out var value); return value; } } public uint FinalRange { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4031, out var value); return (uint)value; } } public int LSBDepth { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4037, out var value); return value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4036, value); } } public OpusFramesize ExpertFrameDuration { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4041, out var value); return (OpusFramesize)value; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4040, (int)value); } } public bool PredictionDisabled { get { NativeOpus.opus_encoder_ctl(NativeHandle, 4043, out var value); return value != 0; } set { NativeOpus.opus_encoder_ctl(NativeHandle, 4042, value ? 1 : 0); } } internal NativeOpusEncoder() : base(ownsHandle: true) { } protected override bool ReleaseHandle() { NativeOpus.opus_encoder_destroy(handle); return true; } public static NativeOpusEncoder Create(int sampleRate, int channelCount, OpusApplication application) { int error; NativeOpusEncoder nativeOpusEncoder = NativeOpus.opus_encoder_create(sampleRate, channelCount, (int)application, out error); if (error != 0) { nativeOpusEncoder.Dispose(); throw new Exception($"Failed to create opus encoder: error {error}"); } nativeOpusEncoder._sampleRate = sampleRate; nativeOpusEncoder._numChannels = channelCount; return nativeOpusEncoder; } public unsafe int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { fixed (short* pcm = in_pcm) { fixed (byte* data = out_data) { return NativeOpus.opus_encode(NativeHandle, pcm, frame_size, data, max_data_bytes); } } } public unsafe int Encode(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { fixed (float* pcm = in_pcm) { fixed (byte* data = out_data) { return NativeOpus.opus_encode_float(NativeHandle, pcm, frame_size, data, max_data_bytes); } } } public void ResetState() { NativeOpus.opus_encoder_ctl(NativeHandle, 4028, 0); } public string GetVersionString() { return Marshal.PtrToStringAnsi(NativeOpus.opus_get_version_string()); } } internal class NativeOpusMultistreamDecoder : SafeHandleZeroOrMinusOneIsInvalid, IOpusMultiStreamDecoder, IDisposable { private int _sampleRate; private int _numChannels; private NativeOpusMultistreamDecoder NativeHandle => this; public int SampleRate => _sampleRate; public int NumChannels => _numChannels; public OpusBandwidth Bandwidth { get { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4009, out var value); return (OpusBandwidth)value; } } public uint FinalRange { get { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4031, out var value); return (uint)value; } } public int Gain { get { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4045, out var value); return value; } set { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4034, value); } } public int LastPacketDuration { get { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4039, out var value); return value; } } internal NativeOpusMultistreamDecoder() : base(ownsHandle: true) { } protected override bool ReleaseHandle() { NativeOpus.opus_multistream_decoder_destroy(handle); return true; } public unsafe static NativeOpusMultistreamDecoder Create(int sampleRate, int channelCount, int streams, int coupledStreams, byte[] channelMapping) { fixed (byte* mapping = channelMapping) { int error; NativeOpusMultistreamDecoder nativeOpusMultistreamDecoder = NativeOpus.opus_multistream_decoder_create(sampleRate, channelCount, streams, coupledStreams, mapping, out error); if (error != 0) { nativeOpusMultistreamDecoder.Dispose(); throw new Exception($"Failed to create opus MS decoder: error {error}"); } nativeOpusMultistreamDecoder._sampleRate = sampleRate; nativeOpusMultistreamDecoder._numChannels = channelCount; return nativeOpusMultistreamDecoder; } } public unsafe int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec) { fixed (float* pcm = out_pcm) { if (data.Length == 0) { return NativeOpus.opus_multistream_decode_float(NativeHandle, null, 0, pcm, frame_size, decode_fec ? 1 : 0); } fixed (byte* data2 = data) { return NativeOpus.opus_multistream_decode_float(NativeHandle, data2, data.Length, pcm, frame_size, decode_fec ? 1 : 0); } } } public unsafe int DecodeMultistream(ReadOnlySpan data, Span out_pcm, int frame_size, bool decode_fec) { fixed (short* pcm = out_pcm) { if (data.Length == 0) { return NativeOpus.opus_multistream_decode(NativeHandle, null, 0, pcm, frame_size, decode_fec ? 1 : 0); } fixed (byte* data2 = data) { return NativeOpus.opus_multistream_decode(NativeHandle, data2, data.Length, pcm, frame_size, decode_fec ? 1 : 0); } } } public void ResetState() { NativeOpus.opus_multistream_decoder_ctl(NativeHandle, 4028, 0); } public string GetVersionString() { return Marshal.PtrToStringAnsi(NativeOpus.opus_get_version_string()); } } internal class NativeOpusMultistreamEncoder : SafeHandleZeroOrMinusOneIsInvalid, IOpusMultiStreamEncoder, IDisposable { private int _sampleRate; private int _numChannels; private NativeOpusMultistreamEncoder NativeHandle => this; public int SampleRate => _sampleRate; public int NumChannels => _numChannels; public int Complexity { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4011, out var value); return value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4010, value); } } public bool UseDTX { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4017, out var value); return value != 0; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4016, value ? 1 : 0); } } public int Bitrate { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4003, out var value); return value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4002, value); } } public OpusMode ForceMode { set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 11002, (int)value); } } public bool UseVBR { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4007, out var value); return value != 0; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4006, value ? 1 : 0); } } public OpusApplication Application { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4001, out var value); return (OpusApplication)value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4000, (int)value); } } public OpusBandwidth Bandwidth { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4009, out var value); return (OpusBandwidth)value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4008, (int)value); } } public OpusFramesize ExpertFrameDuration { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4041, out var value); return (OpusFramesize)value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4040, (int)value); } } public uint FinalRange { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4031, out var value); return (uint)value; } } public int Lookahead { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4027, out var value); return value; } } public int LSBDepth { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4037, out var value); return value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4036, value); } } public OpusBandwidth MaxBandwidth { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4005, out var value); return (OpusBandwidth)value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4004, (int)value); } } public int PacketLossPercent { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4015, out var value); return value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4014, value); } } public bool PredictionDisabled { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4043, out var value); return value != 0; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4042, value ? 1 : 0); } } public OpusSignal SignalType { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4025, out var value); return (OpusSignal)value; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4024, (int)value); } } public bool UseConstrainedVBR { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4021, out var value); return value != 0; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4020, value ? 1 : 0); } } public bool UseInbandFEC { get { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4013, out var value); return value != 0; } set { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4012, value ? 1 : 0); } } internal NativeOpusMultistreamEncoder() : base(ownsHandle: true) { } protected override bool ReleaseHandle() { NativeOpus.opus_multistream_encoder_destroy(handle); return true; } public unsafe static NativeOpusMultistreamEncoder Create(int sampleRate, int channelCount, int mapping_family, out int streams, out int coupled_streams, byte[] mapping, OpusApplication application) { fixed (byte* mapping2 = mapping) { int error; NativeOpusMultistreamEncoder nativeOpusMultistreamEncoder = NativeOpus.opus_multistream_surround_encoder_create(sampleRate, channelCount, mapping_family, out streams, out coupled_streams, mapping2, (int)application, out error); if (error != 0) { nativeOpusMultistreamEncoder.Dispose(); throw new Exception($"Failed to create opus MS encoder: error {error}"); } nativeOpusMultistreamEncoder._sampleRate = sampleRate; nativeOpusMultistreamEncoder._numChannels = channelCount; return nativeOpusMultistreamEncoder; } } public unsafe int EncodeMultistream(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { fixed (float* pcm = in_pcm) { fixed (byte* data = out_data) { return NativeOpus.opus_multistream_encode_float(NativeHandle, pcm, frame_size, data, max_data_bytes); } } } public unsafe int EncodeMultistream(ReadOnlySpan in_pcm, int frame_size, Span out_data, int max_data_bytes) { fixed (short* pcm = in_pcm) { fixed (byte* data = out_data) { return NativeOpus.opus_multistream_encode(NativeHandle, pcm, frame_size, data, max_data_bytes); } } } public void ResetState() { NativeOpus.opus_multistream_encoder_ctl(NativeHandle, 4028, 0); } public string GetVersionString() { return Marshal.PtrToStringAnsi(NativeOpus.opus_get_version_string()); } } internal static class NativePlatformUtils { private static bool _cachedPlatformInfoExists = false; private static OSAndArchitecture _cachedPlatformInfo = new OSAndArchitecture(PlatformOperatingSystem.Unknown, PlatformArchitecture.Unknown); private static readonly IDictionary _loadedLibraries = new Dictionary(); private static readonly object _mutex = new object(); private static readonly IReadOnlyDictionary RidInheritanceMappings = new Dictionary { { "android", new string[4] { "linux-bionic", "linux", "unix", "any" } }, { "android-arm", new string[8] { "android", "linux-bionic-arm", "linux-bionic", "linux-arm", "linux", "unix-arm", "unix", "any" } }, { "android-arm64", new string[8] { "android", "linux-bionic-arm64", "linux-bionic", "linux-arm64", "linux", "unix-arm64", "unix", "any" } }, { "android-x64", new string[8] { "android", "linux-bionic-x64", "linux-bionic", "linux-x64", "linux", "unix-x64", "unix", "any" } }, { "android-x86", new string[8] { "android", "linux-bionic-x86", "linux-bionic", "linux-x86", "linux", "unix-x86", "unix", "any" } }, { "any", new string[0] }, { "base", new string[0] }, { "browser", new string[1] { "any" } }, { "browser-wasm", new string[2] { "browser", "any" } }, { "freebsd", new string[2] { "unix", "any" } }, { "freebsd-arm64", new string[4] { "freebsd", "unix-arm64", "unix", "any" } }, { "freebsd-x64", new string[4] { "freebsd", "unix-x64", "unix", "any" } }, { "illumos", new string[2] { "unix", "any" } }, { "illumos-x64", new string[4] { "illumos", "unix-x64", "unix", "any" } }, { "ios", new string[2] { "unix", "any" } }, { "ios-arm", new string[4] { "ios", "unix-arm", "unix", "any" } }, { "ios-arm64", new string[4] { "ios", "unix-arm64", "unix", "any" } }, { "iossimulator", new string[3] { "ios", "unix", "any" } }, { "iossimulator-arm64", new string[6] { "iossimulator", "ios-arm64", "ios", "unix-arm64", "unix", "any" } }, { "iossimulator-x64", new string[6] { "iossimulator", "ios-x64", "ios", "unix-x64", "unix", "any" } }, { "iossimulator-x86", new string[6] { "iossimulator", "ios-x86", "ios", "unix-x86", "unix", "any" } }, { "ios-x64", new string[4] { "ios", "unix-x64", "unix", "any" } }, { "ios-x86", new string[4] { "ios", "unix-x86", "unix", "any" } }, { "linux", new string[2] { "unix", "any" } }, { "linux-arm", new string[4] { "linux", "unix-arm", "unix", "any" } }, { "linux-arm64", new string[4] { "linux", "unix-arm64", "unix", "any" } }, { "linux-armel", new string[4] { "linux", "unix-armel", "unix", "any" } }, { "linux-armv6", new string[4] { "linux", "unix-armv6", "unix", "any" } }, { "linux-bionic", new string[3] { "linux", "unix", "any" } }, { "linux-bionic-arm", new string[6] { "linux-bionic", "linux-arm", "linux", "unix-arm", "unix", "any" } }, { "linux-bionic-arm64", new string[6] { "linux-bionic", "linux-arm64", "linux", "unix-arm64", "unix", "any" } }, { "linux-bionic-x64", new string[6] { "linux-bionic", "linux-x64", "linux", "unix-x64", "unix", "any" } }, { "linux-bionic-x86", new string[6] { "linux-bionic", "linux-x86", "linux", "unix-x86", "unix", "any" } }, { "linux-loongarch64", new string[4] { "linux", "unix-loongarch64", "unix", "any" } }, { "linux-mips64", new string[4] { "linux", "unix-mips64", "unix", "any" } }, { "linux-musl", new string[3] { "linux", "unix", "any" } }, { "linux-musl-arm", new string[6] { "linux-musl", "linux-arm", "linux", "unix-arm", "unix", "any" } }, { "linux-musl-arm64", new string[6] { "linux-musl", "linux-arm64", "linux", "unix-arm64", "unix", "any" } }, { "linux-musl-armel", new string[6] { "linux-musl", "linux-armel", "linux", "unix-armel", "unix", "any" } }, { "linux-musl-armv6", new string[6] { "linux-musl", "linux-armv6", "linux", "unix-armv6", "unix", "any" } }, { "linux-musl-ppc64le", new string[6] { "linux-musl", "linux-ppc64le", "linux", "unix-ppc64le", "unix", "any" } }, { "linux-musl-riscv64", new string[6] { "linux-musl", "linux-riscv64", "linux", "unix-riscv64", "unix", "any" } }, { "linux-musl-s390x", new string[6] { "linux-musl", "linux-s390x", "linux", "unix-s390x", "unix", "any" } }, { "linux-musl-x64", new string[6] { "linux-musl", "linux-x64", "linux", "unix-x64", "unix", "any" } }, { "linux-musl-x86", new string[6] { "linux-musl", "linux-x86", "linux", "unix-x86", "unix", "any" } }, { "linux-ppc64le", new string[4] { "linux", "unix-ppc64le", "unix", "any" } }, { "linux-riscv64", new string[4] { "linux", "unix-riscv64", "unix", "any" } }, { "linux-s390x", new string[4] { "linux", "unix-s390x", "unix", "any" } }, { "linux-x64", new string[4] { "linux", "unix-x64", "unix", "any" } }, { "linux-x86", new string[4] { "linux", "unix-x86", "unix", "any" } }, { "maccatalyst", new string[3] { "ios", "unix", "any" } }, { "maccatalyst-arm64", new string[6] { "maccatalyst", "ios-arm64", "ios", "unix-arm64", "unix", "any" } }, { "maccatalyst-x64", new string[6] { "maccatalyst", "ios-x64", "ios", "unix-x64", "unix", "any" } }, { "osx", new string[2] { "unix", "any" } }, { "osx-arm64", new string[4] { "osx", "unix-arm64", "unix", "any" } }, { "osx-x64", new string[4] { "osx", "unix-x64", "unix", "any" } }, { "solaris", new string[2] { "unix", "any" } }, { "solaris-x64", new string[4] { "solaris", "unix-x64", "unix", "any" } }, { "tvos", new string[2] { "unix", "any" } }, { "tvos-arm64", new string[4] { "tvos", "unix-arm64", "unix", "any" } }, { "tvossimulator", new string[3] { "tvos", "unix", "any" } }, { "tvossimulator-arm64", new string[6] { "tvossimulator", "tvos-arm64", "tvos", "unix-arm64", "unix", "any" } }, { "tvossimulator-x64", new string[6] { "tvossimulator", "tvos-x64", "tvos", "unix-x64", "unix", "any" } }, { "tvos-x64", new string[4] { "tvos", "unix-x64", "unix", "any" } }, { "unix", new string[1] { "any" } }, { "unix-arm", new string[2] { "unix", "any" } }, { "unix-arm64", new string[2] { "unix", "any" } }, { "unix-armel", new string[2] { "unix", "any" } }, { "unix-armv6", new string[2] { "unix", "any" } }, { "unix-loongarch64", new string[2] { "unix", "any" } }, { "unix-mips64", new string[2] { "unix", "any" } }, { "unix-ppc64le", new string[2] { "unix", "any" } }, { "unix-riscv64", new string[2] { "unix", "any" } }, { "unix-s390x", new string[2] { "unix", "any" } }, { "unix-x64", new string[2] { "unix", "any" } }, { "unix-x86", new string[2] { "unix", "any" } }, { "wasi", new string[1] { "any" } }, { "wasi-wasm", new string[2] { "wasi", "any" } }, { "win", new string[1] { "any" } }, { "win-arm", new string[2] { "win", "any" } }, { "win-arm64", new string[2] { "win", "any" } }, { "win-x64", new string[2] { "win", "any" } }, { "win-x86", new string[2] { "win", "any" } } }; internal static OSAndArchitecture GetCurrentPlatform(TextWriter logger) { lock (_mutex) { if (!_cachedPlatformInfoExists) { _cachedPlatformInfo = GetCurrentPlatformInternal(logger); } return _cachedPlatformInfo; } } internal static OSAndArchitecture GetCurrentPlatformInternal(TextWriter logger) { PlatformOperatingSystem platformOperatingSystem = PlatformOperatingSystem.Unknown; PlatformArchitecture platformArchitecture = PlatformArchitecture.Unknown; if (platformOperatingSystem == PlatformOperatingSystem.Unknown) { try { switch (Environment.OSVersion.Platform) { case PlatformID.Win32S: case PlatformID.Win32Windows: case PlatformID.Win32NT: case PlatformID.WinCE: platformOperatingSystem = PlatformOperatingSystem.Windows; break; case PlatformID.Unix: case PlatformID.MacOSX: platformOperatingSystem = ((File.Exists("/proc/sys/kernel/ostype") && File.ReadAllText("/proc/sys/kernel/ostype").StartsWith("Linux", StringComparison.OrdinalIgnoreCase)) ? PlatformOperatingSystem.Linux : ((!File.Exists("/System/Library/CoreServices/SystemVersion.plist")) ? PlatformOperatingSystem.Unix : PlatformOperatingSystem.MacOS)); break; case PlatformID.Xbox: break; } } catch (Exception ex) { logger?.WriteLine(ex.ToString()); } } if (platformOperatingSystem != PlatformOperatingSystem.Unknown && platformArchitecture == PlatformArchitecture.Unknown) { platformArchitecture = TryGetNativeArchitecture(platformOperatingSystem, logger); } if (platformArchitecture == PlatformArchitecture.Unknown) { platformArchitecture = (Environment.Is64BitProcess ? PlatformArchitecture.X64 : PlatformArchitecture.I386); } return new OSAndArchitecture(platformOperatingSystem, platformArchitecture); } internal static NativeLibraryStatus PrepareNativeLibrary(string libraryName, TextWriter logger) { logger?.WriteLine("Preparing native library \"{0}\"", libraryName); OSAndArchitecture currentPlatform = GetCurrentPlatform(logger); logger?.WriteLine("Detected current platform as \"{0}\"", currentPlatform); string text = NormalizeLibraryName(libraryName, currentPlatform); lock (_mutex) { if (_loadedLibraries.TryGetValue(text, out var value)) { logger?.WriteLine("Native library \"{0}\" has already been prepared; nothing to do", libraryName); return value; } if (currentPlatform.OS == PlatformOperatingSystem.Android) { logger?.WriteLine("Probing for " + text + " within local Android .apk"); if (ProbeLibrary(text, currentPlatform, logger) != NativeLibraryStatus.Available) { logger?.WriteLine("Native library \"{0}\" was not found in the local .apk.", libraryName); return NativeLibraryStatus.Unavailable; } return NativeLibraryStatus.Available; } logger?.WriteLine("Probing for an already existing " + text); NativeLibraryStatus nativeLibraryStatus = ProbeLibrary(text, currentPlatform, logger); if (nativeLibraryStatus == NativeLibraryStatus.Available) { logger?.WriteLine("Native library \"{0}\" resolved to an already-existing library. Loading current file as-is.", libraryName); _loadedLibraries[text] = nativeLibraryStatus; return nativeLibraryStatus; } DeleteLocalLibraryIfPresent(text, logger); string path = Path.Combine(Environment.CurrentDirectory, "runtimes"); List list = PermuteLibraryNames(libraryName, currentPlatform); foreach (string item in PermuteArchitectureSpecificDirectoryNames(currentPlatform)) { DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(path, item, "native")); if (!directoryInfo.Exists) { continue; } foreach (string item2 in list) { FileInfo fileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, item2)); if (!fileInfo.Exists) { continue; } if (currentPlatform.OS == PlatformOperatingSystem.Windows || currentPlatform.OS == PlatformOperatingSystem.Linux || currentPlatform.OS == PlatformOperatingSystem.MacOS) { FileInfo fileInfo2 = new FileInfo(Path.Combine(Environment.CurrentDirectory, text)); try { logger?.WriteLine("Resolved native library \"" + libraryName + "\" to " + fileInfo.FullName); fileInfo.CopyTo(fileInfo2.FullName); _loadedLibraries[text] = NativeLibraryStatus.Available; return NativeLibraryStatus.Available; } catch (Exception ex) { logger?.WriteLine(ex.Message); logger?.WriteLine("Could not prepare native library \"" + libraryName + "\" (is the existing library file locked or in use?)"); _loadedLibraries[text] = NativeLibraryStatus.Unknown; return NativeLibraryStatus.Unknown; } } throw new PlatformNotSupportedException($"Don't know yet how to load libraries for {currentPlatform.OS}"); } } logger?.WriteLine("Failed to resolve native library \"{0}\".", libraryName); _loadedLibraries[text] = NativeLibraryStatus.Unavailable; return NativeLibraryStatus.Unavailable; } } internal static string GetRuntimeIdString(this PlatformArchitecture architecture) { return architecture switch { PlatformArchitecture.Unknown => "unknown", PlatformArchitecture.Any => "any", PlatformArchitecture.I386 => "x86", PlatformArchitecture.X64 => "x64", PlatformArchitecture.ArmV7 => "arm", PlatformArchitecture.Arm64 => "arm64", PlatformArchitecture.Armel => "armel", PlatformArchitecture.ArmV6 => "armv6", PlatformArchitecture.Mips64 => "mips64", PlatformArchitecture.PowerPC64 => "ppc64le", PlatformArchitecture.RiscFive => "riscv64", PlatformArchitecture.S390x => "s390x", PlatformArchitecture.Loongarch64 => "loongarch64", PlatformArchitecture.Itanium64 => "ia64", _ => throw new PlatformNotSupportedException("No runtime ID defined for " + architecture), }; } internal static string GetRuntimeIdString(this PlatformOperatingSystem os) { return os switch { PlatformOperatingSystem.Unknown => "unknown", PlatformOperatingSystem.Any => "any", PlatformOperatingSystem.Windows => "win", PlatformOperatingSystem.Linux => "linux", PlatformOperatingSystem.MacOS => "osx", PlatformOperatingSystem.iOS => "ios", PlatformOperatingSystem.iOS_Simulator => "iossimulator", PlatformOperatingSystem.Android => "android", PlatformOperatingSystem.FreeBSD => "freebsd", PlatformOperatingSystem.Illumos => "illumos", PlatformOperatingSystem.Linux_Bionic => "linux-bionic", PlatformOperatingSystem.Linux_Musl => "linux-musl", PlatformOperatingSystem.MacCatalyst => "maccatalyst", PlatformOperatingSystem.Solaris => "solaris", PlatformOperatingSystem.TvOS => "tvos", PlatformOperatingSystem.TvOS_Simulator => "tvossimulator", PlatformOperatingSystem.Unix => "unix", PlatformOperatingSystem.Browser => "browser", PlatformOperatingSystem.Wasi => "wasi", _ => throw new PlatformNotSupportedException("No runtime ID defined for " + os), }; } internal static string[] GetInheritedRuntimeIds(string runtimeId) { if (RidInheritanceMappings.TryGetValue(runtimeId, out var value)) { return value; } return new string[0]; } internal static OSAndArchitecture ParseRuntimeId(ReadOnlySpan runtimeId) { int num = runtimeId.IndexOf('-'); if (num < 0) { return new OSAndArchitecture(TryParseOperatingSystemString(runtimeId), PlatformArchitecture.Unknown); } return new OSAndArchitecture(TryParseOperatingSystemString(runtimeId.Slice(0, num)), TryParseArchitectureString(runtimeId.Slice(num + 1))); } internal static PlatformOperatingSystem TryParseOperatingSystemString(string os) { return TryParseOperatingSystemString(MemoryExtensions.AsSpan(os)); } internal static PlatformOperatingSystem TryParseOperatingSystemString(ReadOnlySpan os) { if (os.Length >= "win".Length && MemoryExtensions.Equals(os.Slice(0, "win".Length), MemoryExtensions.AsSpan("win"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Windows; } if (os.Length >= "linux".Length && MemoryExtensions.Equals(os.Slice(0, "linux".Length), MemoryExtensions.AsSpan("linux"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Linux; } if (os.Length >= "ubuntu".Length && MemoryExtensions.Equals(os.Slice(0, "ubuntu".Length), MemoryExtensions.AsSpan("ubuntu"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Linux; } if (os.Length >= "debian".Length && MemoryExtensions.Equals(os.Slice(0, "debian".Length), MemoryExtensions.AsSpan("debian"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Linux; } if (os.Length >= "osx".Length && MemoryExtensions.Equals(os.Slice(0, "osx".Length), MemoryExtensions.AsSpan("osx"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.MacOS; } if (os.Length >= "ios".Length && MemoryExtensions.Equals(os.Slice(0, "ios".Length), MemoryExtensions.AsSpan("ios"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.iOS; } if (os.Length >= "iossimulator".Length && MemoryExtensions.Equals(os.Slice(0, "iossimulator".Length), MemoryExtensions.AsSpan("iossimulator"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.iOS_Simulator; } if (os.Length >= "android".Length && MemoryExtensions.Equals(os.Slice(0, "android".Length), MemoryExtensions.AsSpan("android"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Android; } if (os.Length >= "freebsd".Length && MemoryExtensions.Equals(os.Slice(0, "freebsd".Length), MemoryExtensions.AsSpan("freebsd"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.FreeBSD; } if (os.Length >= "illumos".Length && MemoryExtensions.Equals(os.Slice(0, "illumos".Length), MemoryExtensions.AsSpan("illumos"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Illumos; } if (os.Length >= "linux-bionic".Length && MemoryExtensions.Equals(os.Slice(0, "linux-bionic".Length), MemoryExtensions.AsSpan("linux-bionic"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Linux_Bionic; } if (os.Length >= "linux-musl".Length && MemoryExtensions.Equals(os.Slice(0, "linux-musl".Length), MemoryExtensions.AsSpan("linux-musl"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Linux_Musl; } if (os.Length >= "maccatalyst".Length && MemoryExtensions.Equals(os.Slice(0, "maccatalyst".Length), MemoryExtensions.AsSpan("maccatalyst"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.MacCatalyst; } if (os.Length >= "solaris".Length && MemoryExtensions.Equals(os.Slice(0, "solaris".Length), MemoryExtensions.AsSpan("solaris"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Solaris; } if (os.Length >= "tvos".Length && MemoryExtensions.Equals(os.Slice(0, "tvos".Length), MemoryExtensions.AsSpan("tvos"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.TvOS; } if (os.Length >= "tvossimulator".Length && MemoryExtensions.Equals(os.Slice(0, "tvossimulator".Length), MemoryExtensions.AsSpan("tvossimulator"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.TvOS_Simulator; } if (os.Length >= "unix".Length && MemoryExtensions.Equals(os.Slice(0, "unix".Length), MemoryExtensions.AsSpan("unix"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Unix; } if (os.Length >= "browser".Length && MemoryExtensions.Equals(os.Slice(0, "browser".Length), MemoryExtensions.AsSpan("browser"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Browser; } if (os.Length >= "wasi".Length && MemoryExtensions.Equals(os.Slice(0, "wasi".Length), MemoryExtensions.AsSpan("wasi"), StringComparison.OrdinalIgnoreCase)) { return PlatformOperatingSystem.Wasi; } return PlatformOperatingSystem.Unknown; } internal static PlatformArchitecture TryParseArchitectureString(string arch) { return TryParseArchitectureString(MemoryExtensions.AsSpan(arch)); } internal static PlatformArchitecture TryParseArchitectureString(ReadOnlySpan arch) { if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("any"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Any; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("x86"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.I386; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("x64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.X64; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("arm"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.ArmV7; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("arm64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Arm64; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("armel"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Armel; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("armv6"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.ArmV6; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("mips64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Mips64; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("ppc64le"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.PowerPC64; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("riscv64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.RiscFive; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("s390x"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.S390x; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("loongarch64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Loongarch64; } if (MemoryExtensions.Equals(arch, MemoryExtensions.AsSpan("ia64"), StringComparison.OrdinalIgnoreCase)) { return PlatformArchitecture.Itanium64; } return PlatformArchitecture.Unknown; } internal static PlatformArchitecture TryGetNativeArchitecture(PlatformOperatingSystem os, TextWriter logger) { switch (os) { case PlatformOperatingSystem.Windows: { KernelInteropWindows.SYSTEM_INFO Info = default(KernelInteropWindows.SYSTEM_INFO); KernelInteropWindows.GetSystemInfo(ref Info); switch (Info.wProcessorArchitecture) { case 0: case 9: if (Marshal.SizeOf((IntPtr)0) != 4) { return PlatformArchitecture.X64; } return PlatformArchitecture.I386; case 5: return PlatformArchitecture.ArmV7; case 18: return PlatformArchitecture.Arm64; case 6: return PlatformArchitecture.Itanium64; default: return PlatformArchitecture.Unknown; } } case PlatformOperatingSystem.Linux: case PlatformOperatingSystem.Android: case PlatformOperatingSystem.Linux_Bionic: case PlatformOperatingSystem.Linux_Musl: case PlatformOperatingSystem.Unix: { PlatformArchitecture? platformArchitecture = KernelInteropLinux.TryGetArchForUnix(logger); if (platformArchitecture.HasValue) { return platformArchitecture.Value; } break; } } return PlatformArchitecture.Unknown; } private static void DeleteLocalLibraryIfPresent(string normalizedLibraryName, TextWriter logger) { FileInfo fileInfo = new FileInfo(Path.Combine(Environment.CurrentDirectory, normalizedLibraryName)); if (fileInfo.Exists) { try { logger?.WriteLine("Clobbering existing file " + fileInfo.FullName); fileInfo.Delete(); } catch (Exception) { logger?.WriteLine("Failed to clean up \"" + fileInfo.FullName + "\" (is it locked or in use?)"); } } } private static List PermuteArchitectureSpecificDirectoryNames(OSAndArchitecture platformInfo) { string text = platformInfo.OS.GetRuntimeIdString() + "-" + platformInfo.Architecture.GetRuntimeIdString(); string[] inheritedRuntimeIds = GetInheritedRuntimeIds(text); List list = new List(inheritedRuntimeIds.Length + 1); list.Add(text); if (platformInfo.OS == PlatformOperatingSystem.Windows) { list.Add("win10-" + platformInfo.Architecture.GetRuntimeIdString()); list.Add("win81-" + platformInfo.Architecture.GetRuntimeIdString()); list.Add("win8-" + platformInfo.Architecture.GetRuntimeIdString()); list.Add("win7-" + platformInfo.Architecture.GetRuntimeIdString()); list.Add("win10"); list.Add("win81"); list.Add("win8"); list.Add("win7"); } list.AddRange(inheritedRuntimeIds); return list; } private static string LibraryNameWithoutExtension(string libraryName) { if (!libraryName.Contains(".")) { return libraryName; } string text = libraryName.ToLowerInvariant(); if (text.EndsWith(".dll") || text.EndsWith(".so") || text.EndsWith(".dylib")) { return libraryName.Substring(0, libraryName.LastIndexOf('.')); } return libraryName; } private static string NormalizeLibraryName(string requestedName, OSAndArchitecture platformInfo) { string text = LibraryNameWithoutExtension(requestedName); if (platformInfo.OS == PlatformOperatingSystem.Windows) { return text + ".dll"; } if (platformInfo.OS == PlatformOperatingSystem.Linux || platformInfo.OS == PlatformOperatingSystem.Android || platformInfo.OS == PlatformOperatingSystem.Linux_Bionic || platformInfo.OS == PlatformOperatingSystem.Linux_Musl || platformInfo.OS == PlatformOperatingSystem.Unix) { if (!text.StartsWith("lib", StringComparison.Ordinal)) { return "lib" + text + ".so"; } return text + ".so"; } if (platformInfo.OS == PlatformOperatingSystem.iOS || platformInfo.OS == PlatformOperatingSystem.iOS_Simulator || platformInfo.OS == PlatformOperatingSystem.MacOS || platformInfo.OS == PlatformOperatingSystem.MacCatalyst) { if (!text.StartsWith("lib", StringComparison.Ordinal)) { return "lib" + text + ".dylib"; } return text + ".dylib"; } return requestedName; } private static List PermuteLibraryNames(string requestedName, OSAndArchitecture platformInfo) { List list = new List(16); string text = LibraryNameWithoutExtension(requestedName); if (platformInfo.OS == PlatformOperatingSystem.Windows) { list.Add(text + ".dll"); list.Add("lib" + text + ".dll"); if (platformInfo.Architecture == PlatformArchitecture.I386) { list.Add(text + "_x86.dll"); list.Add("lib" + text + "_x86.dll"); list.Add(text + "x86.dll"); list.Add("lib" + text + "x86.dll"); list.Add(text + "32.dll"); list.Add("lib" + text + "32.dll"); list.Add(text + "_32.dll"); list.Add("lib" + text + "_32.dll"); list.Add(text + "-32.dll"); list.Add("lib" + text + "-32.dll"); } if (platformInfo.Architecture == PlatformArchitecture.X64) { list.Add(text + "_x64.dll"); list.Add("lib" + text + "_x64.dll"); list.Add(text + "x64.dll"); list.Add("lib" + text + "x64.dll"); list.Add(text + "64.dll"); list.Add("lib" + text + "64.dll"); list.Add(text + "_64.dll"); list.Add("lib" + text + "_64.dll"); list.Add(text + "-64.dll"); list.Add("lib" + text + "-64.dll"); } } else if (platformInfo.OS == PlatformOperatingSystem.Linux || platformInfo.OS == PlatformOperatingSystem.Android || platformInfo.OS == PlatformOperatingSystem.Linux_Bionic || platformInfo.OS == PlatformOperatingSystem.Linux_Musl || platformInfo.OS == PlatformOperatingSystem.Unix) { list.Add(text + ".so"); list.Add("lib" + text + ".so"); } else if (platformInfo.OS == PlatformOperatingSystem.MacOS || platformInfo.OS == PlatformOperatingSystem.MacCatalyst || platformInfo.OS == PlatformOperatingSystem.iOS || platformInfo.OS == PlatformOperatingSystem.iOS_Simulator) { list.Add(text + ".dylib"); list.Add("lib" + text + ".dylib"); } else { list.Add(requestedName); } return list; } internal static NativeLibraryStatus ProbeLibrary(string libName, OSAndArchitecture platformInfo, TextWriter logger) { try { if (platformInfo.OS == PlatformOperatingSystem.Windows) { IntPtr intPtr = IntPtr.Zero; try { logger?.WriteLine("Attempting to load " + libName + " as a windows .dll"); KernelInteropWindows.GetLastError(); intPtr = KernelInteropWindows.LoadLibraryExW(libName, IntPtr.Zero, 4096u); if (intPtr == IntPtr.Zero) { uint lastError = KernelInteropWindows.GetLastError(); if (lastError != 0) { uint num = 0x80070000u | lastError; switch (num) { case 2147942526u: logger?.WriteLine($"Win32 error 0x{num:X8}: File {libName} not found"); break; case 2147942593u: logger?.WriteLine($"Win32 error 0x{num:X8}: Invalid binary format while loading library {libName}"); break; default: logger?.WriteLine($"Win32 error 0x{num:X8} while loading library {libName}"); break; } } else { logger?.WriteLine("Native library " + libName + " not found."); } return NativeLibraryStatus.Unavailable; } logger?.WriteLine("Native library " + libName + " found!"); return NativeLibraryStatus.Available; } finally { if (intPtr != IntPtr.Zero) { KernelInteropWindows.FreeLibrary(intPtr); } } } if (platformInfo.OS == PlatformOperatingSystem.Linux || platformInfo.OS == PlatformOperatingSystem.Android || platformInfo.OS == PlatformOperatingSystem.Linux_Bionic || platformInfo.OS == PlatformOperatingSystem.Linux_Musl || platformInfo.OS == PlatformOperatingSystem.Unix) { IntPtr intPtr2 = IntPtr.Zero; try { logger?.WriteLine("Attempting to load " + libName + " as a linux .so"); intPtr2 = KernelInteropLinux.dlopen(libName, 2); if (intPtr2 == IntPtr.Zero) { IntPtr intPtr3 = KernelInteropLinux.dlerror(); if (intPtr3 != IntPtr.Zero) { string text = Marshal.PtrToStringAnsi(intPtr3); if (!string.IsNullOrEmpty(text)) { logger?.WriteLine($"Error while loading library {libName}: {text}"); } else { logger?.WriteLine(libName + " could not be loaded."); } } else { logger?.WriteLine(libName + " could not be loaded."); } return NativeLibraryStatus.Unavailable; } logger?.WriteLine("Native library " + libName + " found!"); return NativeLibraryStatus.Available; } finally { if (intPtr2 != IntPtr.Zero) { KernelInteropLinux.dlclose(intPtr2); } } } if (platformInfo.OS == PlatformOperatingSystem.MacOS || platformInfo.OS == PlatformOperatingSystem.MacCatalyst || platformInfo.OS == PlatformOperatingSystem.iOS || platformInfo.OS == PlatformOperatingSystem.iOS_Simulator) { IntPtr intPtr4 = IntPtr.Zero; try { logger?.WriteLine("Attempting to load " + libName + " as a macOS .dylib"); intPtr4 = KernelInteropMacOS.dlopen(libName, 2); if (intPtr4 == IntPtr.Zero) { IntPtr intPtr5 = KernelInteropMacOS.dlerror(); if (intPtr5 != IntPtr.Zero) { string text2 = Marshal.PtrToStringAnsi(intPtr5); if (!string.IsNullOrEmpty(text2)) { logger?.WriteLine($"Error while loading library {libName}: {text2}"); } else { logger?.WriteLine(libName + " could not be loaded."); } } else { logger?.WriteLine(libName + " could not be loaded."); } return NativeLibraryStatus.Unavailable; } logger?.WriteLine("Native library " + libName + " found!"); return NativeLibraryStatus.Available; } finally { if (intPtr4 != IntPtr.Zero) { KernelInteropMacOS.dlclose(intPtr4); } } } } catch (Exception value) { logger?.WriteLine(value); } return NativeLibraryStatus.Unknown; } } internal readonly struct OSAndArchitecture : IEquatable { public PlatformOperatingSystem OS { get; } public PlatformArchitecture Architecture { get; } public OSAndArchitecture(PlatformOperatingSystem OS, PlatformArchitecture architecture) { this.OS = OS; Architecture = architecture; } public override string ToString() { return OS.GetRuntimeIdString() + "-" + Architecture.GetRuntimeIdString(); } public override int GetHashCode() { return OS.GetHashCode() * 17 + Architecture.GetHashCode() * 37119; } public override bool Equals(object other) { if (other == null || GetType() != other.GetType()) { return false; } return Equals((OSAndArchitecture)other); } public bool Equals(OSAndArchitecture other) { if (OS == other.OS) { return Architecture == other.Architecture; } return false; } public static bool operator ==(OSAndArchitecture left, OSAndArchitecture right) { return left.Equals(right); } public static bool operator !=(OSAndArchitecture left, OSAndArchitecture right) { return !(left == right); } } internal enum PlatformArchitecture { Unknown, Any, I386, X64, ArmV7, Arm64, Armel, ArmV6, Mips64, PowerPC64, RiscFive, S390x, Loongarch64, Itanium64 } internal enum PlatformOperatingSystem { Unknown, Any, Windows, Linux, MacOS, iOS, iOS_Simulator, Android, FreeBSD, Illumos, Linux_Bionic, Linux_Musl, MacCatalyst, Solaris, TvOS, TvOS_Simulator, Unix, Browser, Wasi } } namespace Concentus.Common { internal static class Autocorrelation { private const int QC = 10; private const int QS = 14; internal static void silk_autocorr(int[] results, out int scale, short[] inputData, int inputDataSize, int correlationCount) { int num = Inlines.silk_min_int(inputDataSize, correlationCount); scale = _celt_autocorr(inputData, results, num - 1, inputDataSize); } internal static int _celt_autocorr(short[] x, int[] ac, int lag, int n) { int num = n - lag; short[] array = new short[n]; short[] array2 = x; int num2 = 0; int num3 = 1 + (n << 7); if ((n & 1) != 0) { num3 += Inlines.SHR32(Inlines.MULT16_16(array2[0], array2[0]), 9); } for (int i = n & 1; i < n; i += 2) { num3 += Inlines.SHR32(Inlines.MULT16_16(array2[i], array2[i]), 9); num3 += Inlines.SHR32(Inlines.MULT16_16(array2[i + 1], array2[i + 1]), 9); } num2 = Inlines.celt_ilog2(num3) - 30 + 10; num2 /= 2; if (num2 > 0) { for (int i = 0; i < n; i++) { array[i] = (short)Inlines.PSHR32(array2[i], num2); } array2 = array; } else { num2 = 0; } CeltPitchXCorr.pitch_xcorr(array2, 0, array2, 0, ac, num, lag + 1); for (int j = 0; j <= lag; j++) { int i = j + num; int num4 = 0; for (; i < n; i++) { num4 = Inlines.MAC16_16(num4, array2[i], array2[i - j]); } ac[j] += num4; } num2 = 2 * num2; if (num2 <= 0) { ac[0] += Inlines.SHL32(1, -num2); } if (ac[0] < 268435456) { int num5 = 29 - Inlines.EC_ILOG((uint)ac[0]); for (int i = 0; i <= lag; i++) { ac[i] = Inlines.SHL32(ac[i], num5); } num2 -= num5; } else if (ac[0] >= 536870912) { int num6 = 1; if (ac[0] >= 1073741824) { num6++; } for (int i = 0; i <= lag; i++) { ac[i] = Inlines.SHR32(ac[i], num6); } num2 += num6; } return num2; } internal static int _celt_autocorr(int[] x, int[] ac, int[] window, int overlap, int lag, int n) { int num = n - lag; int[] array = new int[n]; int[] array2; if (overlap == 0) { array2 = x; } else { for (int i = 0; i < n; i++) { array[i] = x[i]; } for (int i = 0; i < overlap; i++) { array[i] = Inlines.MULT16_16_Q15(x[i], window[i]); array[n - i - 1] = Inlines.MULT16_16_Q15(x[n - i - 1], window[i]); } array2 = array; } int num2 = 0; int num3 = 1 + (n << 7); if ((n & 1) != 0) { num3 += Inlines.SHR32(Inlines.MULT16_16(array2[0], array2[0]), 9); } for (int i = n & 1; i < n; i += 2) { num3 += Inlines.SHR32(Inlines.MULT16_16(array2[i], array2[i]), 9); num3 += Inlines.SHR32(Inlines.MULT16_16(array2[i + 1], array2[i + 1]), 9); } num2 = Inlines.celt_ilog2(num3) - 30 + 10; num2 /= 2; if (num2 > 0) { for (int i = 0; i < n; i++) { array[i] = Inlines.PSHR32(array2[i], num2); } array2 = array; } else { num2 = 0; } CeltPitchXCorr.pitch_xcorr(array2, 0, array2, 0, ac, num, lag + 1); for (int j = 0; j <= lag; j++) { int i = j + num; int num4 = 0; for (; i < n; i++) { num4 = Inlines.MAC16_16(num4, array2[i], array2[i - j]); } ac[j] += num4; } num2 = 2 * num2; if (num2 <= 0) { ac[0] += Inlines.SHL32(1, -num2); } if (ac[0] < 268435456) { int num5 = 29 - Inlines.EC_ILOG((uint)ac[0]); for (int i = 0; i <= lag; i++) { ac[i] = Inlines.SHL32(ac[i], num5); } num2 -= num5; } else if (ac[0] >= 536870912) { int num6 = 1; if (ac[0] >= 1073741824) { num6++; } for (int i = 0; i <= lag; i++) { ac[i] = Inlines.SHR32(ac[i], num6); } num2 += num6; } return num2; } internal static void silk_warped_autocorrelation(int[] corr, out int scale, short[] input, int warping_Q16, int length, int order) { Span span = new int[order + 1]; Span span2 = new long[order + 1]; for (int i = 0; i < length; i++) { int num = Inlines.silk_LSHIFT32(input[i], 14); for (int j = 0; j < order; j += 2) { int num2 = Inlines.silk_SMLAWB(span[j], span[j + 1] - num, warping_Q16); span[j] = num; span2[j] += Inlines.silk_RSHIFT64(Inlines.silk_SMULL(num, span[0]), 18); num = Inlines.silk_SMLAWB(span[j + 1], span[j + 2] - num2, warping_Q16); span[j + 1] = num2; span2[j + 1] += Inlines.silk_RSHIFT64(Inlines.silk_SMULL(num2, span[0]), 18); } span[order] = num; span2[order] += Inlines.silk_RSHIFT64(Inlines.silk_SMULL(num, span[0]), 18); } int a = Inlines.silk_CLZ64(span2[0]) - 35; a = Inlines.silk_LIMIT(a, -22, 20); scale = -(10 + a); if (a >= 0) { for (int j = 0; j < order + 1; j++) { corr[j] = (int)Inlines.silk_LSHIFT64(span2[j], a); } } else { for (int j = 0; j < order + 1; j++) { corr[j] = (int)Inlines.silk_RSHIFT64(span2[j], -a); } } } } internal class EntropyCoder { private const int EC_WINDOW_SIZE = 32; private const int EC_UINT_BITS = 8; internal const int BITRES = 3; private const int EC_SYM_BITS = 8; private const int EC_CODE_BITS = 32; private const uint EC_SYM_MAX = 255u; private const uint EC_CODE_SHIFT = 23u; private const uint EC_CODE_TOP = 2147483648u; private const uint EC_CODE_BOT = 8388608u; private const int EC_CODE_EXTRA = 7; internal uint storage; internal uint end_offs; internal uint end_window; internal int nend_bits; internal int nbits_total; internal uint offs; internal uint rng; internal uint val; internal uint ext; internal int rem; internal int error; private static readonly uint[] correction = new uint[8] { 35733u, 38967u, 42495u, 46340u, 50535u, 55109u, 60097u, 65535u }; internal EntropyCoder() { Reset(); } internal void Reset() { storage = 0u; end_offs = 0u; end_window = 0u; nend_bits = 0; offs = 0u; rng = 0u; val = 0u; ext = 0u; rem = 0; error = 0; } internal void Assign(EntropyCoder other) { storage = other.storage; end_offs = other.end_offs; end_window = other.end_window; nend_bits = other.nend_bits; nbits_total = other.nbits_total; offs = other.offs; rng = other.rng; val = other.val; ext = other.ext; rem = other.rem; error = other.error; } internal int read_byte(ReadOnlySpan buf) { if (offs >= storage) { return 0; } return buf[(int)offs++]; } internal int read_byte_from_end(ReadOnlySpan buf) { if (end_offs >= storage) { return 0; } return buf[(int)(storage - ++end_offs)]; } internal int write_byte(Span buf, uint _value) { if (offs + end_offs >= storage) { return -1; } buf[(int)offs++] = (byte)_value; return 0; } internal int write_byte_at_end(Span buf, uint _value) { if (offs + end_offs >= storage) { return -1; } buf[(int)(storage - ++end_offs)] = (byte)_value; return 0; } internal void dec_normalize(ReadOnlySpan buf) { while (rng <= 8388608) { nbits_total += 8; rng <<= 8; int num = rem; rem = read_byte(buf); num = ((num << 8) | rem) >> 1; val = (uint)((int)((val << 8) + (0xFFuL & (ulong)(~num))) & 0x7FFFFFFF); } } internal void dec_init(ReadOnlySpan buf, uint _storage) { storage = _storage; end_offs = 0u; end_window = 0u; nend_bits = 0; nbits_total = 9; offs = 0u; rng = 128u; rem = read_byte(buf); val = rng - 1 - (uint)(rem >> 1); error = 0; dec_normalize(buf); } internal uint decode(uint _ft) { ext = rng / _ft; uint num = val / ext; return _ft - Inlines.EC_MINI(num + 1, _ft); } internal uint decode_bin(uint _bits) { ext = rng >> (int)_bits; uint num = val / ext; return (uint)(1 << (int)_bits) - Inlines.EC_MINI(num + 1, (uint)(1 << (int)_bits)); } internal void dec_update(ReadOnlySpan buf, uint _fl, uint _fh, uint _ft) { uint num = ext * (_ft - _fh); val -= num; rng = ((_fl != 0) ? (ext * (_fh - _fl)) : (rng - num)); dec_normalize(buf); } internal int dec_bit_logp(ReadOnlySpan buf, uint _logp) { uint num = rng; uint num2 = val; uint num3 = num >> (int)_logp; int num4 = ((num2 < num3) ? 1 : 0); if (num4 == 0) { val = num2 - num3; } rng = ((num4 != 0) ? num3 : (num - num3)); dec_normalize(buf); return num4; } internal int dec_icdf(ReadOnlySpan buf, byte[] _icdf, uint _ftb) { uint num = rng; uint num2 = val; uint num3 = num >> (int)_ftb; int num4 = -1; uint num5; do { num5 = num; num = num3 * _icdf[++num4]; } while (num2 < num); val = num2 - num; rng = num5 - num; dec_normalize(buf); return num4; } internal int dec_icdf(ReadOnlySpan buf, byte[] _icdf, int _icdf_offset, uint _ftb) { uint num = rng; uint num2 = val; uint num3 = num >> (int)_ftb; int num4 = _icdf_offset - 1; uint num5; do { num5 = num; num = num3 * _icdf[++num4]; } while (num2 < num); val = num2 - num; rng = num5 - num; dec_normalize(buf); return num4 - _icdf_offset; } internal uint dec_uint(ReadOnlySpan buf, uint _ft) { _ft--; int num = Inlines.EC_ILOG(_ft); uint num2; if (num > 8) { num -= 8; uint ft = (_ft >> num) + 1; num2 = decode(ft); dec_update(buf, num2, num2 + 1, ft); uint num3 = (num2 << num) | dec_bits(buf, (uint)num); if (num3 <= _ft) { return num3; } error = 1; return _ft; } _ft++; num2 = decode(_ft); dec_update(buf, num2, num2 + 1, _ft); return num2; } internal uint dec_bits(ReadOnlySpan buf, uint _bits) { uint num = end_window; int num2 = nend_bits; if ((uint)num2 < _bits) { do { num |= (uint)(read_byte_from_end(buf) << num2); num2 += 8; } while (num2 <= 24); } int result = (int)num & ((1 << (int)_bits) - 1); num >>= (int)_bits; num2 -= (int)_bits; end_window = num; nend_bits = num2; nbits_total += (int)_bits; return (uint)result; } internal void enc_carry_out(Span buf, int _c) { if ((long)_c != 255) { int num = _c >> 8; if (rem >= 0) { error |= write_byte(buf, (uint)(rem + num)); } if (ext != 0) { uint value = (uint)((255 + num) & 0xFF); do { error |= write_byte(buf, value); } while (--ext != 0); } rem = _c & 0xFF; } else { ext++; } } internal void enc_normalize(Span buf) { while (rng <= 8388608) { enc_carry_out(buf, (int)(val >> 23)); val = (val << 8) & 0x7FFFFFFF; rng <<= 8; nbits_total += 8; } } internal void enc_init(uint _size) { end_offs = 0u; end_window = 0u; nend_bits = 0; nbits_total = 33; offs = 0u; rng = 2147483648u; rem = -1; val = 0u; ext = 0u; storage = _size; error = 0; } internal void encode(Span buf, uint _fl, uint _fh, uint _ft) { uint num = rng / _ft; if (_fl != 0) { val += rng - num * (_ft - _fl); rng = num * (_fh - _fl); } else { rng -= num * (_ft - _fh); } enc_normalize(buf); } internal void encode_bin(Span buf, uint _fl, uint _fh, uint _bits) { uint num = rng >> (int)_bits; if (_fl != 0) { val += (uint)((int)rng - (int)num * ((1 << (int)_bits) - (int)_fl)); rng = num * (_fh - _fl); } else { rng -= (uint)((int)num * ((1 << (int)_bits) - (int)_fh)); } enc_normalize(buf); } internal void enc_bit_logp(Span buf, int _val, uint _logp) { uint num = rng; uint num2 = val; uint num3 = num >> (int)_logp; num -= num3; if (_val != 0) { val = num2 + num; } rng = ((_val != 0) ? num3 : num); enc_normalize(buf); } internal void enc_icdf(Span buf, int _s, byte[] _icdf, uint _ftb) { uint num = rng >> (int)_ftb; if (_s > 0) { val += rng - num * _icdf[_s - 1]; rng = num * (uint)(_icdf[_s - 1] - _icdf[_s]); } else { rng -= num * _icdf[_s]; } enc_normalize(buf); } internal void enc_icdf(Span buf, int _s, byte[] _icdf, int icdf_ptr, uint _ftb) { uint num = rng >> (int)_ftb; if (_s > 0) { val += rng - num * _icdf[icdf_ptr + _s - 1]; rng = num * (uint)(_icdf[icdf_ptr + _s - 1] - _icdf[icdf_ptr + _s]); } else { rng -= num * _icdf[icdf_ptr + _s]; } enc_normalize(buf); } internal void enc_uint(Span buf, uint _fl, uint _ft) { _ft--; int num = Inlines.EC_ILOG(_ft); if (num > 8) { num -= 8; uint ft = (_ft >> num) + 1; uint num2 = _fl >> num; encode(buf, num2, num2 + 1, ft); enc_bits(buf, _fl & (uint)((1 << num) - 1), (uint)num); } else { encode(buf, _fl, _fl + 1, _ft + 1); } } internal void enc_bits(Span buf, uint _fl, uint _bits) { uint num = end_window; int num2 = nend_bits; if (num2 + _bits > 32) { do { error |= write_byte_at_end(buf, num & 0xFF); num >>= 8; num2 -= 8; } while (num2 >= 8); } num |= _fl << num2; num2 += (int)_bits; end_window = num; nend_bits = num2; nbits_total += (int)_bits; } internal void enc_patch_initial_bits(Span buf, uint _val, uint _nbits) { int num = (int)(8 - _nbits); uint num2 = (uint)((1 << (int)_nbits) - 1 << num); if (offs != 0) { buf[0] = (byte)((buf[0] & ~num2) | (_val << num)); } else if (rem >= 0) { rem = (int)((((uint)rem & ~num2) | _val) << num); } else if (rng <= (uint)(int.MinValue >>> (int)_nbits)) { val = (val & ~(num2 << 23)) | (_val << (int)(23L + (long)num)); } else { error = -1; } } internal void enc_shrink(Span buf, uint _size) { Arrays.MemMoveByte(buf, (int)(_size - end_offs), (int)(storage - end_offs), (int)end_offs); storage = _size; } internal uint range_bytes() { return offs; } internal int get_error() { return error; } internal int tell() { return nbits_total - Inlines.EC_ILOG(rng); } internal uint tell_frac() { int num = nbits_total << 3; int num2 = Inlines.EC_ILOG(rng); int num3 = (int)(rng >> num2 - 16); uint num4 = (uint)((num3 >> 12) - 8); num4 += ((num3 > correction[num4]) ? 1u : 0u); num2 = (int)((num2 << 3) + num4); return (uint)(num - num2); } internal void enc_done(Span buf) { int num = 32 - Inlines.EC_ILOG(rng); uint num2 = 2147483647u >> num; uint num3 = (val + num2) & ~num2; if ((num3 | num2) >= val + rng) { num++; num2 >>= 1; num3 = (val + num2) & ~num2; } while (num > 0) { enc_carry_out(buf, (int)(num3 >> 23)); num3 = (num3 << 8) & 0x7FFFFFFF; num -= 8; } if (rem >= 0 || ext != 0) { enc_carry_out(buf, 0); } uint num4 = end_window; int num5; for (num5 = nend_bits; num5 >= 8; num5 -= 8) { error |= write_byte_at_end(buf, num4 & 0xFF); num4 >>= 8; } if (error != 0) { return; } Arrays.MemSetWithOffset(buf, 0, (int)offs, (int)(storage - offs - end_offs)); if (num5 <= 0) { return; } if (end_offs >= storage) { error = -1; return; } num = -num; if (offs + end_offs >= storage && num < num5) { num4 &= (uint)((1 << num) - 1); error = -1; } buf[(int)(storage - end_offs - 1)] |= (byte)num4; } } internal static class Inlines { private const MethodImplOptions INLINE_ATTR = MethodImplOptions.AggressiveInlining; private static readonly short[] sqrt_C = new short[5] { 23175, 11561, -3011, 1699, -664 }; private const short log2_C0 = -6793; [Conditional("DEBUG")] internal static void OpusAssert(bool condition, string message = "Unknown error") { } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16SU(int a, int b) { return (short)a * (ushort)b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16SU(short a, ushort b) { return a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16SU(int a, uint b) { return a * (int)b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_Q16(short a, int b) { return ADD32(MULT16_16(a, SHR(b, 16)), SHR(MULT16_16SU(a, b & 0xFFFF), 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_Q16(int a, int b) { return ADD32(MULT16_16(a, SHR(b, 16)), SHR(MULT16_16SU(a, b & 0xFFFF), 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_P16(short a, int b) { return ADD32(MULT16_16(a, SHR(b, 16)), PSHR(MULT16_16SU(a, b & 0xFFFF), 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_P16(int a, int b) { return ADD32(MULT16_16(a, SHR(b, 16)), PSHR(MULT16_16SU(a, b & 0xFFFF), 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_Q15(short a, int b) { return (a * (b >> 16) << 1) + (a * (b & 0xFFFF) >> 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_32_Q15(int a, int b) { return (a * (b >> 16) << 1) + (a * (b & 0xFFFF) >> 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT32_32_Q31(int a, int b) { return ADD32(ADD32(SHL(MULT16_16(SHR(a, 16), SHR(b, 16)), 1), SHR(MULT16_16SU(SHR(a, 16), b & 0xFFFF), 15)), SHR(MULT16_16SU(SHR(b, 16), a & 0xFFFF), 15)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short QCONST16(float x, int bits) { return (short)(0.5 + (double)(x * (float)(1 << bits))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int QCONST32(float x, int bits) { return (int)(0.5 + (double)(x * (float)(1 << bits))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short NEG16(short x) { return (short)(-x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int NEG16(int x) { return -x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int NEG32(int x) { return -x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short EXTRACT16(int x) { return (short)x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int EXTEND32(short x) { return x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int EXTEND32(int x) { return x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SHR16(short a, int shift) { return (short)(a >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SHR16(int a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SHL16(short a, int shift) { return (short)((ushort)a << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SHL16(int a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SHR32(int a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SHL32(int a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int PSHR32(int a, int shift) { return SHR32(a + (EXTEND32(1) << shift >> 1), shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short PSHR16(short a, int shift) { return SHR16((short)(a + (1 << shift >> 1)), shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int PSHR16(int a, int shift) { return SHR32(a + (1 << shift >> 1), shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int VSHR32(int a, int shift) { if (shift <= 0) { return SHL32(a, -shift); } return SHR32(a, shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int SHR(int a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int SHL(int a, int shift) { return SHL32(a, shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int SHR(short a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int SHL(short a, int shift) { return SHL32(a, shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int PSHR(int a, int shift) { return SHR(a + (EXTEND32(1) << shift >> 1), shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SATURATE(int x, int a) { if (x <= a) { if (x >= -a) { return x; } return -a; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SATURATE16(int x) { return EXTRACT16((x > 32767) ? 32767 : ((x < -32768) ? (-32768) : x)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short ROUND16(short x, short a) { return EXTRACT16(PSHR32(x, a)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int ROUND16(int x, int a) { return PSHR32(x, a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int PDIV32(int a, int b) { return a / b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short HALF16(short x) { return SHR16(x, 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int HALF16(int x) { return SHR32(x, 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int HALF32(int x) { return SHR32(x, 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short ADD16(short a, short b) { return (short)(a + b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int ADD16(int a, int b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SUB16(short a, short b) { return (short)(a - b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SUB16(int a, int b) { return a - b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int ADD32(int a, int b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SUB32(int a, int b) { return a - b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_16(short a, short b) { return (short)(a * b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_16(int a, int b) { return a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16(int a, int b) { return a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16(short a, short b) { return a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_16(short c, short a, short b) { return c + a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_16(int c, short a, short b) { return c + a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_16(int c, int a, int b) { return c + a * b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_32_Q15(int c, short a, short b) { return ADD32(c, ADD32(MULT16_16(a, SHR(b, 15)), SHR(MULT16_16(a, b & 0x7FFF), 15))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_32_Q15(int c, int a, int b) { return ADD32(c, ADD32(MULT16_16(a, SHR(b, 15)), SHR(MULT16_16(a, b & 0x7FFF), 15))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_32_Q16(int c, short a, short b) { return ADD32(c, ADD32(MULT16_16(a, SHR(b, 16)), SHR(MULT16_16SU(a, b & 0xFFFF), 16))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAC16_32_Q16(int c, int a, int b) { return ADD32(c, ADD32(MULT16_16(a, SHR(b, 16)), SHR(MULT16_16SU(a, b & 0xFFFF), 16))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q11_32(short a, short b) { return SHR(MULT16_16(a, b), 11); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q11_32(int a, int b) { return SHR(MULT16_16(a, b), 11); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_Q11(short a, short b) { return (short)SHR(MULT16_16(a, b), 11); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q11(int a, int b) { return SHR(MULT16_16(a, b), 11); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_Q13(short a, short b) { return (short)SHR(MULT16_16(a, b), 13); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q13(int a, int b) { return SHR(MULT16_16(a, b), 13); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_Q14(short a, short b) { return (short)SHR(MULT16_16(a, b), 14); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q14(int a, int b) { return SHR(MULT16_16(a, b), 14); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_Q15(short a, short b) { return (short)SHR(MULT16_16(a, b), 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_Q15(int a, int b) { return SHR(MULT16_16(a, b), 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_P13(short a, short b) { return (short)SHR(ADD32(4096, MULT16_16(a, b)), 13); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_P13(int a, int b) { return SHR(ADD32(4096, MULT16_16(a, b)), 13); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_P14(short a, short b) { return (short)SHR(ADD32(8192, MULT16_16(a, b)), 14); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_P14(int a, int b) { return SHR(ADD32(8192, MULT16_16(a, b)), 14); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MULT16_16_P15(short a, short b) { return (short)SHR(ADD32(16384, MULT16_16(a, b)), 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MULT16_16_P15(int a, int b) { return SHR(ADD32(16384, MULT16_16(a, b)), 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short DIV32_16(int a, short b) { return (short)(a / b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int DIV32_16(int a, int b) { return a / b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int DIV32(int a, int b) { return a / b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SAT16(int x) { return (x > 32767) ? short.MaxValue : ((x < -32768) ? short.MinValue : ((short)x)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short SIG2WORD16(int x) { x = PSHR32(x, 12); x = MAX32(x, -32768); x = MIN32(x, 32767); return EXTRACT16(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MIN(short a, short b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MAX(short a, short b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MIN16(short a, short b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short MAX16(short a, short b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MIN16(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAX16(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float MIN16(float a, float b) { if (!(a < b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float MAX16(float a, float b) { if (!(a > b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MIN(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAX(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int IMIN(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint IMIN(uint a, uint b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int IMAX(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MIN32(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MAX32(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float MIN32(float a, float b) { if (!(a < b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float MAX32(float a, float b) { if (!(a > b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int ABS16(int x) { if (x >= 0) { return x; } return -x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float ABS16(float x) { if (!(x < 0f)) { return x; } return 0f - x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short ABS16(short x) { return (short)((x < 0) ? (-x) : x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int ABS32(int x) { if (x >= 0) { return x; } return -x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint celt_udiv(uint n, uint d) { return n / d; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_udiv(int n, int d) { return n / d; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_sudiv(int n, int d) { return n / d; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_div(int a, int b) { return MULT32_32_Q31(a, celt_rcp(b)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_ilog2(int x) { return EC_ILOG((uint)x) - 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_zlog2(int x) { if (x > 0) { return celt_ilog2(x); } return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_maxabs16(Span x, int x_ptr, int len) { int num = 0; int num2 = 0; for (int i = x_ptr; i < len + x_ptr; i++) { num = MAX32(num, x[i]); num2 = MIN32(num2, x[i]); } return MAX32(EXTEND32(num), -EXTEND32(num2)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_maxabs32(Span x, int len) { int a = 0; int num = 0; for (int i = 0; i < len; i++) { a = MAX32(a, x[i]); num = MIN32(num, x[i]); } return MAX32(a, -num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_maxabs32(Span x, int x_ptr, int len) { int a = 0; int num = 0; for (int i = x_ptr; i < x_ptr + len; i++) { a = MAX32(a, x[i]); num = MIN32(num, x[i]); } return MAX32(a, -num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short celt_maxabs32(Span x, int x_ptr, int len) { short a = 0; short num = 0; for (int i = x_ptr; i < x_ptr + len; i++) { a = MAX16(a, x[i]); num = MIN16(num, x[i]); } return MAX(a, (short)(-num)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int FRAC_MUL16(int a, int b) { return 16384 + (short)a * (short)b >> 15; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint isqrt32(uint _val) { uint num = 0u; int num2 = EC_ILOG(_val) - 1 >> 1; uint num3 = (uint)(1 << num2); do { uint num4 = (num << 1) + num3 << num2; if (num4 <= _val) { num += num3; _val -= num4; } num3 >>= 1; num2--; } while (num2 >= 0); return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_sqrt(int x) { if (x == 0) { return 0; } if (x >= 1073741824) { return 32767; } int num = (celt_ilog2(x) >> 1) - 7; x = VSHR32(x, 2 * num); short a = (short)(x - 32768); return VSHR32(ADD16(sqrt_C[0], MULT16_16_Q15(a, ADD16(sqrt_C[1], MULT16_16_Q15(a, ADD16(sqrt_C[2], MULT16_16_Q15(a, ADD16(sqrt_C[3], MULT16_16_Q15(a, sqrt_C[4])))))))), 7 - num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_rcp(int x) { int num = celt_ilog2(x); int b = VSHR32(x, num - 15) - 32768; int a = ADD16(30840, MULT16_16_Q15(-15420, b)); a = SUB16(a, MULT16_16_Q15(a, ADD16(MULT16_16_Q15(a, b), ADD16(a, -32768)))); a = SUB16(a, ADD16(1, MULT16_16_Q15(a, ADD16(MULT16_16_Q15(a, b), ADD16(a, -32768))))); return VSHR32(EXTEND32(a), num - 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_rsqrt_norm(int x) { int num = x - 32768; int num2 = ADD16(23557, MULT16_16_Q15(num, ADD16(-13490, MULT16_16_Q15(num, 6713)))); int num3 = MULT16_16_Q15(num2, num2); int a = SHL16(SUB16(ADD16(MULT16_16_Q15(num3, num), num3), 16384), 1); return ADD16(num2, MULT16_16_Q15(num2, MULT16_16_Q15(a, SUB16(MULT16_16_Q15(a, 12288), 16384)))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int frac_div32(int a, int b) { int shift = celt_ilog2(b) - 29; a = VSHR32(a, shift); b = VSHR32(b, shift); int a2 = ROUND16(celt_rcp(ROUND16(b, 16)), 3); int a3 = MULT16_32_Q15(a2, a); int b2 = PSHR32(a, 2) - MULT32_32_Q31(a3, b); a3 = ADD32(a3, SHL32(MULT16_32_Q15(a2, b2), 2)); if (a3 >= 536870912) { return int.MaxValue; } if (a3 <= -536870912) { return -2147483647; } return SHL32(a3, 2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_log2(int x) { if (x == 0) { return -32767; } int num = celt_ilog2(x); int a = VSHR32(x, num - 15) - 32768 - 16384; int a2 = ADD16(-6793, MULT16_16_Q15(a, ADD16(15746, MULT16_16_Q15(a, ADD16(-5217, MULT16_16_Q15(a, ADD16(2545, MULT16_16_Q15(a, -1401)))))))); return SHL16((short)(num - 13), 10) + SHR16(a2, 4); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_exp2_frac(int x) { int num = SHL16(x, 4); return ADD16(16383, MULT16_16_Q15(num, ADD16(22804, MULT16_16_Q15(num, ADD16(14819, MULT16_16_Q15(10204, num)))))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_exp2(int x) { int num = SHR16(x, 10); if (num > 14) { return 2130706432; } if (num < -15) { return 0; } return VSHR32(EXTEND32((int)(short)celt_exp2_frac((short)(x - SHL16((short)num, 10)))), -num - 2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_atan01(int x) { return MULT16_16_P15(x, ADD32(32767, MULT16_16_P15(x, ADD32(-21, MULT16_16_P15(x, ADD32(-11943, MULT16_16_P15(4936, x))))))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_atan2p(int y, int x) { if (y < x) { int num = celt_div(SHL32(EXTEND32(y), 15), x); if (num >= 32767) { num = 32767; } return SHR32(celt_atan01(EXTRACT16(num)), 1); } int num2 = celt_div(SHL32(EXTEND32(x), 15), y); if (num2 >= 32767) { num2 = 32767; } return 25736 - SHR16(celt_atan01(EXTRACT16(num2)), 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int celt_cos_norm(int x) { x &= 0x1FFFF; if (x > SHL32(EXTEND32(1), 16)) { x = SUB32(SHL32(EXTEND32(1), 17), x); } if ((x & 0x7FFF) != 0) { if (x < SHL32(EXTEND32(1), 15)) { return _celt_cos_pi_2(EXTRACT16(x)); } return NEG32(_celt_cos_pi_2(EXTRACT16(65536 - x))); } if ((x & 0xFFFF) != 0) { return 0; } if ((x & 0x1FFFF) != 0) { return -32767; } return 32767; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int _celt_cos_pi_2(int x) { int num = MULT16_16_P15(x, x); return ADD32(1, MIN32(32766, ADD32(SUB16(32767, num), MULT16_16_P15(num, ADD32(-7651, MULT16_16_P15(num, ADD32(8277, MULT16_16_P15(-626, num)))))))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short FLOAT2INT16(float x) { x *= 32768f; if (x < -32768f) { x = -32768f; } if (x > 32767f) { x = 32767f; } return (short)x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ROR32(int a32, int rot) { return (int)silk_ROR32((uint)a32, rot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_ROR32(uint a32, int rot) { int num = -rot; if (rot == 0) { return a32; } if (rot < 0) { return (a32 << num) | (a32 >> 32 - num); } return (a32 << 32 - rot) | (a32 >> rot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_MUL(int a32, int b32) { return a32 * b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_MUL_uint(uint a32, uint b32) { return a32 * b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_MLA(int a32, int b32, int c32) { return silk_ADD32(a32, b32 * c32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_MLA_uint(uint a32, uint b32, uint c32) { return (int)silk_ADD32(a32, b32 * c32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULTT(int a32, int b32) { return (a32 >> 16) * (b32 >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLATT(int a32, int b32, int c32) { return silk_ADD32(a32, (b32 >> 16) * (c32 >> 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_SMLALBB(long a64, short b16, short c16) { return silk_ADD64(a64, b16 * c16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_SMULL(int a32, int b32) { return (long)a32 * (long)b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD32_ovflw(int a, int b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD32_ovflw(uint a, uint b) { return (int)(a + b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SUB32_ovflw(int a, int b) { return a - b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_MLA_ovflw(int a32, int b32, int c32) { return silk_ADD32_ovflw((uint)a32, (uint)(b32 * c32)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLABB_ovflw(int a32, int b32, int c32) { return silk_ADD32_ovflw(a32, (short)b32 * (short)c32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULBB(int a32, int b32) { return (short)a32 * (short)b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULWB(int a32, int b32) { return (int)((long)a32 * (long)(short)b32 >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLABB(int a32, int b32, int c32) { return a32 + (short)b32 * (short)c32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_DIV32_16(int a32, int b32) { return a32 / b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_DIV32(int a32, int b32) { return a32 / b32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_ADD16(short a, short b) { return (short)(a + b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD32(int a, int b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_ADD32(uint a, uint b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_ADD64(long a, long b) { return a + b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_SUB16(short a, short b) { return (short)(a - b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SUB32(int a, int b) { return a - b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_SUB64(long a, long b) { return a - b; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SAT8(int a) { if (a <= 255) { if (a >= 0) { return a; } return 0; } return 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SAT16(int a) { if (a <= 32767) { if (a >= -32768) { return a; } return -32768; } return 32767; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SAT32(long a) { if (a <= int.MaxValue) { if (a >= int.MinValue) { return (int)a; } return int.MinValue; } return int.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_ADD_SAT16(short a16, short b16) { return (short)silk_SAT16(silk_ADD32(a16, b16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_SAT32(int a32, int b32) { if (((a32 + b32) & int.MinValue) != 0) { if (((a32 | b32) & 0x80000000u) != 0L) { return a32 + b32; } return int.MaxValue; } if ((a32 & b32 & 0x80000000u) == 0L) { return a32 + b32; } return int.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_ADD_SAT64(long a64, long b64) { if (((a64 + b64) & long.MinValue) != 0L) { if (((a64 | b64) & long.MinValue) != 0L) { return a64 + b64; } return long.MaxValue; } if ((a64 & b64 & long.MinValue) == 0L) { return a64 + b64; } return long.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_SUB_SAT16(short a16, short b16) { return (short)silk_SAT16(silk_SUB32(a16, b16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SUB_SAT32(int a32, int b32) { if (((a32 - b32) & int.MinValue) != 0) { if (((a32 ^ 0x80000000u) & b32 & 0x80000000u) == 0L) { return a32 - b32; } return int.MaxValue; } if ((a32 & (b32 ^ 0x80000000u) & 0x80000000u) == 0L) { return a32 - b32; } return int.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_SUB_SAT64(long a64, long b64) { if (((a64 - b64) & long.MinValue) != 0L) { if (((a64 ^ long.MinValue) & b64 & long.MinValue) == 0L) { return a64 - b64; } return long.MaxValue; } if ((a64 & (b64 ^ long.MinValue) & long.MinValue) == 0L) { return a64 - b64; } return long.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static sbyte silk_ADD_POS_SAT8(sbyte a, sbyte b) { return (sbyte)((((a + b) & 0x80) != 0) ? 127 : (a + b)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_ADD_POS_SAT16(short a, short b) { return (short)((((a + b) & 0x8000) != 0) ? 32767 : (a + b)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_POS_SAT32(int a, int b) { if (((a + b) & 0x80000000u) == 0L) { return a + b; } return int.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_ADD_POS_SAT64(long a, long b) { if (((a + b) & long.MinValue) == 0L) { return a + b; } return long.MaxValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static sbyte silk_LSHIFT8(sbyte a, int shift) { return (sbyte)(a << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_LSHIFT16(short a, int shift) { return (short)(a << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LSHIFT32(int a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_LSHIFT64(long a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LSHIFT(int a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LSHIFT_ovflw(int a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_LSHIFT_uint(uint a, int shift) { return a << shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LSHIFT_SAT32(int a, int shift) { return silk_LSHIFT32(silk_LIMIT(a, silk_RSHIFT32(int.MinValue, shift), silk_RSHIFT32(int.MaxValue, shift)), shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static sbyte silk_RSHIFT8(sbyte a, int shift) { return (sbyte)(a >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_RSHIFT16(short a, int shift) { return (short)(a >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_RSHIFT32(int a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_RSHIFT(int a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_RSHIFT64(long a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_RSHIFT_uint(uint a, int shift) { return a >> shift; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_LSHIFT(int a, int b, int shift) { return a + (b << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_LSHIFT32(int a, int b, int shift) { return a + (b << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_ADD_LSHIFT_uint(uint a, uint b, int shift) { return a + (b << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_RSHIFT(int a, int b, int shift) { return a + (b >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_ADD_RSHIFT32(int a, int b, int shift) { return a + (b >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint silk_ADD_RSHIFT_uint(uint a, uint b, int shift) { return a + (b >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SUB_LSHIFT32(int a, int b, int shift) { return a - (b << shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SUB_RSHIFT32(int a, int b, int shift) { return a - (b >> shift); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_RSHIFT_ROUND(int a, int shift) { if (shift != 1) { return (a >> shift - 1) + 1 >> 1; } return (a >> 1) + (a & 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_RSHIFT_ROUND64(long a, int shift) { if (shift != 1) { return (a >> shift - 1) + 1 >> 1; } return (a >> 1) + (a & 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_min(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_max(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float silk_min(float a, float b) { if (!(a < b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float silk_max(float a, float b) { if (!(a > b)) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int SILK_CONST(float number, int scale) { return (int)((double)(number * (float)(1L << scale)) + 0.5); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_min_int(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_min_16(short a, short b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_min_32(int a, int b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_min_64(long a, long b) { if (a >= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_max_int(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_max_16(short a, short b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_max_32(int a, int b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_max_64(long a, long b) { if (a <= b) { return b; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static float silk_LIMIT(float a, float limit1, float limit2) { if (!(limit1 > limit2)) { if (!(a > limit2)) { if (!(a < limit1)) { return a; } return limit1; } return limit2; } if (!(a > limit1)) { if (!(a < limit2)) { return a; } return limit2; } return limit1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LIMIT(int a, int limit1, int limit2) { return silk_LIMIT_32(a, limit1, limit2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LIMIT_int(int a, int limit1, int limit2) { return silk_LIMIT_32(a, limit1, limit2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static short silk_LIMIT_16(short a, short limit1, short limit2) { if (limit1 <= limit2) { if (a <= limit2) { if (a >= limit1) { return a; } return limit1; } return limit2; } if (a <= limit1) { if (a >= limit2) { return a; } return limit2; } return limit1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_LIMIT_32(int a, int limit1, int limit2) { if (limit1 <= limit2) { if (a <= limit2) { if (a >= limit1) { return a; } return limit1; } return limit2; } if (a <= limit1) { if (a >= limit2) { return a; } return limit2; } return limit1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_abs(int a) { if (a <= 0) { return -a; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_abs_int16(int a) { return (a ^ (a >> 15)) - (a >> 15); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_abs_int32(int a) { return (a ^ (a >> 31)) - (a >> 31); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_abs_int64(long a) { if (a <= 0) { return -a; } return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_sign(int a) { return (a > 0) ? 1 : ((a < 0) ? (-1) : 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_RAND(int seed) { return silk_MLA_ovflw(907633515, seed, 196314165); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMMUL(int a32, int b32) { return (int)silk_RSHIFT64(silk_SMULL(a32, b32), 32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLAWT(int a32, int b32, int c32) { return a32 + (b32 >> 16) * (c32 >> 16) + ((b32 & 0xFFFF) * (c32 >> 16) >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_DIV32_varQ(int a32, int b32, int Qres) { int num = silk_CLZ32(silk_abs(a32)) - 1; int num2 = silk_LSHIFT(a32, num); int num3 = silk_CLZ32(silk_abs(b32)) - 1; int num4 = silk_LSHIFT(b32, num3); int num5 = silk_DIV32_16(536870911, silk_RSHIFT(num4, 16)); int num6 = silk_SMULWB(num2, num5); num2 = silk_SUB32_ovflw(num2, silk_LSHIFT_ovflw(silk_SMMUL(num4, num6), 3)); num6 = silk_SMLAWB(num6, num2, num5); int num7 = 29 + num - num3 - Qres; if (num7 < 0) { return silk_LSHIFT_SAT32(num6, -num7); } if (num7 < 32) { return silk_RSHIFT(num6, num7); } return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_INVERSE32_varQ(int b32, int Qres) { int num = silk_CLZ32(silk_abs(b32)) - 1; int num2 = silk_LSHIFT(b32, num); int num3 = silk_DIV32_16(536870911, (short)silk_RSHIFT(num2, 16)); int a = silk_LSHIFT(num3, 16); int b33 = silk_LSHIFT(536870912 - silk_SMULWB(num2, num3), 3); a = silk_SMLAWW(a, b33, num3); int num4 = 61 - num - Qres; if (num4 <= 0) { return silk_LSHIFT_SAT32(a, -num4); } if (num4 < 32) { return silk_RSHIFT(a, num4); } return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLAWB(int a32, int b32, int c32) { return a32 + silk_SMULWB(b32, c32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULWT(int a32, int b32) { return (a32 >> 16) * (b32 >> 16) + ((a32 & 0xFFFF) * (b32 >> 16) >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULBT(int a32, int b32) { return (short)a32 * (b32 >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLABT(int a32, int b32, int c32) { return a32 + (short)b32 * (c32 >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_SMLAL(long a64, int b32, int c32) { return silk_ADD64(a64, (long)b32 * (long)c32); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MatrixSet(T[] Matrix_base_adr, int Matrix_ptr, int row, int column, int N, T value) { Matrix_base_adr[Matrix_ptr + row * N + column] = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MatrixGetPointer(int row, int column, int N) { return row * N + column; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T MatrixGet(T[] Matrix_base_adr, int row, int column, int N) { return Matrix_base_adr[row * N + column]; } internal static T MatrixGet(T[] Matrix_base_adr, int matrix_ptr, int row, int column, int N) { return Matrix_base_adr[matrix_ptr + row * N + column]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MatrixSet(T[] Matrix_base_adr, int row, int column, int N, T value) { Matrix_base_adr[row * N + column] = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMULWW(int a32, int b32) { return silk_MLA(silk_SMULWB(a32, b32), a32, silk_RSHIFT_ROUND(b32, 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SMLAWW(int a32, int b32, int c32) { return silk_MLA(silk_SMLAWB(a32, b32, c32), b32, silk_RSHIFT_ROUND(c32, 16)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_CLZ64(long input) { int num = (int)silk_RSHIFT64(input, 32); if (num == 0) { return 32 + silk_CLZ32((int)input); } return silk_CLZ32(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_CLZ32(int in32) { if (in32 != 0) { return 32 - EC_ILOG((uint)in32); } return 32; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void silk_CLZ_FRAC(int input, out int lz, out int frac_Q7) { frac_Q7 = silk_ROR32(input, 24 - (lz = silk_CLZ32(input))) & 0x7F; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_SQRT_APPROX(int x) { if (x <= 0) { return 0; } silk_CLZ_FRAC(x, out var lz, out var frac_Q); int num = (((lz & 1) == 0) ? 46214 : 32768); num >>= silk_RSHIFT(lz, 1); return silk_SMLAWB(num, num, silk_SMULBB(213, frac_Q)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int MUL32_FRAC_Q(int a32, int b32, int Q) { return (int)silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_lin2log(int inLin) { silk_CLZ_FRAC(inLin, out var lz, out var frac_Q); return silk_LSHIFT(31 - lz, 7) + silk_SMLAWB(frac_Q, silk_MUL(frac_Q, 128 - frac_Q), 179); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_log2lin(int inLog_Q7) { if (inLog_Q7 < 0) { return 0; } if (inLog_Q7 >= 3967) { return int.MaxValue; } int num = silk_LSHIFT(1, silk_RSHIFT(inLog_Q7, 7)); int num2 = inLog_Q7 & 0x7F; if (inLog_Q7 < 2048) { return silk_ADD_RSHIFT32(num, silk_MUL(num, silk_SMLAWB(num2, silk_SMULBB(num2, 128 - num2), -174)), 7); } return silk_MLA(num, silk_RSHIFT(num, 7), silk_SMLAWB(num2, silk_SMULBB(num2, 128 - num2), -174)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void silk_interpolate(short[] xi, short[] x0, short[] x1, int ifact_Q2, int d) { for (int i = 0; i < d; i++) { xi[i] = (short)silk_ADD_RSHIFT(x0[i], silk_SMULBB(x1[i] - x0[i], ifact_Q2), 2); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_inner_prod_aligned_scale(short[] inVec1, short[] inVec2, int scale, int len) { int num = 0; for (int i = 0; i < len; i++) { num = silk_ADD_RSHIFT32(num, silk_SMULBB(inVec1[i], inVec2[i]), scale); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void silk_scale_copy_vector16(Span data_out, int data_out_ptr, Span data_in, int data_in_ptr, int gain_Q16, int dataSize) { for (int i = 0; i < dataSize; i++) { data_out[data_out_ptr + i] = (short)silk_SMULWB(gain_Q16, data_in[data_in_ptr + i]); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void silk_scale_vector32_Q26_lshift_18(int[] data1, int data1_ptr, int gain_Q26, int dataSize) { for (int i = data1_ptr; i < data1_ptr + dataSize; i++) { data1[i] = (int)silk_RSHIFT64(silk_SMULL(data1[i], gain_Q26), 8); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_inner_prod(short[] inVec1, int inVec1_ptr, short[] inVec2, int inVec2_ptr, int len) { int num = 0; for (int i = 0; i < len; i++) { num = MAC16_16(num, inVec1[inVec1_ptr + i], inVec2[inVec2_ptr + i]); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int silk_inner_prod_self(short[] inVec, int inVec_ptr, int len) { int num = 0; for (int i = inVec_ptr; i < inVec_ptr + len; i++) { num = MAC16_16(num, inVec[i], inVec[i]); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static long silk_inner_prod16_aligned_64(short[] inVec1, int inVec1_ptr, short[] inVec2, int inVec2_ptr, int len) { long num = 0L; for (int i = 0; i < len; i++) { num = silk_SMLALBB(num, inVec1[inVec1_ptr + i], inVec2[inVec2_ptr + i]); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint EC_MINI(uint a, uint b) { return a + ((b - a) & (uint)((b < a) ? (-1) : 0)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int EC_CLZ(uint x) { if (x == 0) { return 0; } x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; uint num = x - ((x >> 1) & 0x55555555); num = ((num >> 2) & 0x33333333) + (num & 0x33333333); num = ((num >> 4) + num) & 0xF0F0F0F; num += num >> 8; num += num >> 16; num &= 0x3F; return (int)(1 - num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int EC_ILOG(uint x) { if (x == 0) { return 1; } x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; uint num = x - ((x >> 1) & 0x55555555); num = ((num >> 2) & 0x33333333) + (num & 0x33333333); num = ((num >> 4) + num) & 0xF0F0F0F; num += num >> 8; num += num >> 16; return (int)(num & 0x3F); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int abs(int a) { if (a < 0) { return -a; } return a; } } internal class SpeexResampler : IResampler, IDisposable { private class FuncDef { public double[] table; public int oversample; public static readonly double[] kaiser12_table = new double[68] { 0.99859849, 1.0, 0.99859849, 0.99440475, 0.98745105, 0.97779076, 0.9654977, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.7262997, 0.69451601, 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.343018, 0.3150649, 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, 0.0706395, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, 0.02584161, 0.02127838, 0.0173625, 0.01402878, 0.01121463, 0.00886058, 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 5.27734E-05, 1E-05, 0.0 }; public static readonly double[] kaiser10_table = new double[36] { 0.99537781, 1.0, 0.99537781, 0.98162644, 0.95908712, 0.92831446, 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, 0.56155915, 0.5011968, 0.44221549, 0.38553619, 0.33194107, 0.28205962, 0.23636152, 0.19515633, 0.15859932, 0.1267028, 0.09935205, 0.07632451, 0.05731132, 0.0419398, 0.02979584, 0.0204451, 0.01345224, 0.00839739, 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.0, 0.0 }; public static readonly double[] kaiser8_table = new double[36] { 0.99635258, 1.0, 0.99635258, 0.98548012, 0.96759014, 0.943022, 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, 0.6345175, 0.58014482, 0.52566725, 0.47185369, 0.4194115, 0.36897272, 0.32108304, 0.27619388, 0.23465776, 0.1967267, 0.1625538, 0.13219758, 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.0236949, 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.0005, 0.0 }; public static readonly double[] kaiser6_table = new double[36] { 0.99733006, 1.0, 0.99733006, 0.98935595, 0.97618418, 0.95799003, 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.0869312, 0.067226, 0.0503182, 0.03607231, 0.02432151, 0.01487334, 0.00752, 0.0 }; public FuncDef(double[] t, int os) { table = t; oversample = os; } } private class QualityMapping { public int base_length; public int oversample; public float downsample_bandwidth; public float upsample_bandwidth; public FuncDef window_func; public static readonly QualityMapping[] quality_map = new QualityMapping[11] { new QualityMapping(8, 4, 0.83f, 0.86f, new FuncDef(FuncDef.kaiser6_table, 32)), new QualityMapping(16, 4, 0.85f, 0.88f, new FuncDef(FuncDef.kaiser6_table, 32)), new QualityMapping(32, 4, 0.882f, 0.91f, new FuncDef(FuncDef.kaiser6_table, 32)), new QualityMapping(48, 8, 0.895f, 0.917f, new FuncDef(FuncDef.kaiser8_table, 32)), new QualityMapping(64, 8, 0.921f, 0.94f, new FuncDef(FuncDef.kaiser8_table, 32)), new QualityMapping(80, 16, 0.922f, 0.94f, new FuncDef(FuncDef.kaiser10_table, 32)), new QualityMapping(96, 16, 0.94f, 0.945f, new FuncDef(FuncDef.kaiser10_table, 32)), new QualityMapping(128, 16, 0.95f, 0.95f, new FuncDef(FuncDef.kaiser10_table, 32)), new QualityMapping(160, 16, 0.96f, 0.96f, new FuncDef(FuncDef.kaiser10_table, 32)), new QualityMapping(192, 32, 0.968f, 0.968f, new FuncDef(FuncDef.kaiser12_table, 64)), new QualityMapping(256, 32, 0.975f, 0.975f, new FuncDef(FuncDef.kaiser12_table, 64)) }; private QualityMapping(int bl, int os, float dsb, float usb, FuncDef wf) { base_length = bl; oversample = os; downsample_bandwidth = dsb; upsample_bandwidth = usb; window_func = wf; } } private delegate int resampler_basic_func(int channel_index, Span input, int input_ptr, ref int in_len, Span output, int output_ptr, ref int out_len); private const int FIXED_STACK_ALLOC = 8192; private int in_rate; private int out_rate; private int num_rate; private int den_rate; private int quality; private int nb_channels; private int filt_len; private int mem_alloc_size; private int buffer_size; private int int_advance; private int frac_advance; private float cutoff; private int oversample; private int initialised; private int started; private int[] last_sample; private int[] samp_frac_num; private int[] magic_samples; private float[] mem; private float[] sinc_table; private int sinc_table_length; private resampler_basic_func resampler_ptr; private int in_stride; private int out_stride; public int Quality { get { return quality; } set { if (value > 10 || value < 0) { throw new ArgumentException("Quality must be between 0 and 10"); } if (quality != value) { quality = value; if (initialised != 0) { update_filter(); } } } } public int InputStride { get { return in_stride; } set { in_stride = value; } } public int OutputStride { get { return out_stride; } set { out_stride = value; } } public int InputLatency => filt_len / 2; public int OutputLatencySamples => (filt_len / 2 * den_rate + (num_rate >> 1)) / num_rate; public TimeSpan OutputLatency => TimeSpan.FromTicks((long)OutputLatencySamples * 10000000L / out_rate); private static short FLOAT2INT(float x) { if (!(x < -32768f)) { if (!(x > 32767f)) { return (short)x; } return short.MaxValue; } return short.MinValue; } private static double compute_func(float x, FuncDef func) { float num = x * (float)func.oversample; int num2 = (int)Math.Floor(num); float num3 = num - (float)num2; double num4 = -0.1666666667 * (double)num3 + 0.1666666667 * (double)(num3 * num3 * num3); double num5 = (double)num3 + 0.5 * (double)(num3 * num3) - 0.5 * (double)(num3 * num3 * num3); double num6 = -0.3333333333 * (double)num3 + 0.5 * (double)(num3 * num3) - 0.1666666667 * (double)(num3 * num3 * num3); double num7 = 1.0 - num4 - num5 - num6; return num6 * func.table[num2] + num7 * func.table[num2 + 1] + num5 * func.table[num2 + 2] + num4 * func.table[num2 + 3]; } private static float sinc(float cutoff, float x, int N, FuncDef window_func) { float num = x * cutoff; if (Math.Abs(x) < 1E-06f) { return cutoff; } if (Math.Abs(x) > 0.5f * (float)N) { return 0f; } return (float)((double)cutoff * Math.Sin(Math.PI * (double)num) / (Math.PI * (double)num) * compute_func(Math.Abs(2f * x / (float)N), window_func)); } private static void cubic_coef(float frac, Span interp) { interp[0] = -0.16667f * frac + 0.16667f * frac * frac * frac; interp[1] = frac + 0.5f * frac * frac - 0.5f * frac * frac * frac; interp[3] = -0.33333f * frac + 0.5f * frac * frac - 0.16667f * frac * frac * frac; interp[2] = 1f - interp[0] - interp[1] - interp[3]; } private int resampler_basic_direct_single(int channel_index, Span input, int input_ptr, ref int in_len, Span output, int output_ptr, ref int out_len) { int num = filt_len; int num2 = 0; int num3 = last_sample[channel_index]; int num4 = samp_frac_num[channel_index]; while (num3 < in_len && num2 < out_len) { int num5 = num4 * num; int num6 = input_ptr + num3; float num7 = 0f; for (int i = 0; i < num; i++) { num7 += sinc_table[num5 + i] * input[num6 + i]; } output[output_ptr + out_stride * num2++] = num7; num3 += int_advance; num4 += frac_advance; if (num4 >= den_rate) { num4 -= den_rate; num3++; } } last_sample[channel_index] = num3; samp_frac_num[channel_index] = num4; return num2; } private int resampler_basic_interpolate_single(int channel_index, Span input, int input_ptr, ref int in_len, Span output, int output_ptr, ref int out_len) { int num = filt_len; int num2 = 0; int num3 = last_sample[channel_index]; int num4 = samp_frac_num[channel_index]; Span interp = stackalloc float[4]; Span span = stackalloc float[4]; while (num3 < in_len && num2 < out_len) { int num5 = input_ptr + num3; int num6 = num4 * oversample / den_rate; float frac = (float)(num4 * oversample % den_rate) / (float)den_rate; span[0] = 0f; span[1] = 0f; span[2] = 0f; span[3] = 0f; for (int i = 0; i < num; i++) { float num7 = input[num5 + i]; span[0] += num7 * sinc_table[4 + (i + 1) * oversample - num6 - 2]; span[1] += num7 * sinc_table[4 + (i + 1) * oversample - num6 - 1]; span[2] += num7 * sinc_table[4 + (i + 1) * oversample - num6]; span[3] += num7 * sinc_table[4 + (i + 1) * oversample - num6 + 1]; } cubic_coef(frac, interp); float num8 = interp[0] * span[0] + interp[1] * span[1] + interp[2] * span[2] + interp[3] * span[3]; output[output_ptr + out_stride * num2++] = num8; num3 += int_advance; num4 += frac_advance; if (num4 >= den_rate) { num4 -= den_rate; num3++; } } last_sample[channel_index] = num3; samp_frac_num[channel_index] = num4; return num2; } private void update_filter() { int num = filt_len; oversample = QualityMapping.quality_map[quality].oversample; filt_len = QualityMapping.quality_map[quality].base_length; if (num_rate > den_rate) { cutoff = QualityMapping.quality_map[quality].downsample_bandwidth * (float)den_rate / (float)num_rate; filt_len = filt_len * num_rate / den_rate; filt_len = ((filt_len - 1) & -8) + 8; if (2 * den_rate < num_rate) { oversample >>= 1; } if (4 * den_rate < num_rate) { oversample >>= 1; } if (8 * den_rate < num_rate) { oversample >>= 1; } if (16 * den_rate < num_rate) { oversample >>= 1; } if (oversample < 1) { oversample = 1; } } else { cutoff = QualityMapping.quality_map[quality].upsample_bandwidth; } if (den_rate <= 16 * (oversample + 8)) { if (sinc_table == null) { sinc_table = new float[filt_len * den_rate]; } else if (sinc_table_length < filt_len * den_rate) { sinc_table = new float[filt_len * den_rate]; sinc_table_length = filt_len * den_rate; } for (int i = 0; i < den_rate; i++) { for (int j = 0; j < filt_len; j++) { sinc_table[i * filt_len + j] = sinc(cutoff, (float)(j - filt_len / 2 + 1) - (float)i / (float)den_rate, filt_len, QualityMapping.quality_map[quality].window_func); } } resampler_ptr = resampler_basic_direct_single; } else { if (sinc_table == null) { sinc_table = new float[filt_len * oversample + 8]; } else if (sinc_table_length < filt_len * oversample + 8) { sinc_table = new float[filt_len * oversample + 8]; sinc_table_length = filt_len * oversample + 8; } for (int k = -4; k < oversample * filt_len + 4; k++) { sinc_table[k + 4] = sinc(cutoff, (float)k / (float)oversample - (float)(filt_len / 2), filt_len, QualityMapping.quality_map[quality].window_func); } resampler_ptr = resampler_basic_interpolate_single; } int_advance = num_rate / den_rate; frac_advance = num_rate % den_rate; if (mem == null) { mem_alloc_size = filt_len - 1 + buffer_size; mem = new float[nb_channels * mem_alloc_size]; for (int l = 0; l < nb_channels * mem_alloc_size; l++) { mem[l] = 0f; } } else if (started == 0) { mem_alloc_size = filt_len - 1 + buffer_size; mem = new float[nb_channels * mem_alloc_size]; for (int m = 0; m < nb_channels * mem_alloc_size; m++) { mem[m] = 0f; } } else if (filt_len > num) { int num2 = mem_alloc_size; if (filt_len - 1 + buffer_size > mem_alloc_size) { mem_alloc_size = filt_len - 1 + buffer_size; mem = new float[nb_channels * mem_alloc_size]; } for (int num3 = nb_channels - 1; num3 >= 0; num3--) { int num4 = num; num4 = num + 2 * magic_samples[num3]; for (int num5 = num - 2 + magic_samples[num3]; num5 >= 0; num5--) { mem[num3 * mem_alloc_size + num5 + magic_samples[num3]] = mem[num3 * num2 + num5]; } for (int num5 = 0; num5 < magic_samples[num3]; num5++) { mem[num3 * mem_alloc_size + num5] = 0f; } magic_samples[num3] = 0; if (filt_len > num4) { int num5; for (num5 = 0; num5 < num4 - 1; num5++) { mem[num3 * mem_alloc_size + (filt_len - 2 - num5)] = mem[num3 * mem_alloc_size + (num4 - 2 - num5)]; } for (; num5 < filt_len - 1; num5++) { mem[num3 * mem_alloc_size + (filt_len - 2 - num5)] = 0f; } last_sample[num3] += (filt_len - num4) / 2; } else { magic_samples[num3] = (num4 - filt_len) / 2; for (int num5 = 0; num5 < filt_len - 1 + magic_samples[num3]; num5++) { mem[num3 * mem_alloc_size + num5] = mem[num3 * mem_alloc_size + num5 + magic_samples[num3]]; } } } } else { if (filt_len >= num) { return; } for (int n = 0; n < nb_channels; n++) { int num6 = magic_samples[n]; magic_samples[n] = (num - filt_len) / 2; for (int num7 = 0; num7 < filt_len - 1 + magic_samples[n] + num6; num7++) { mem[n * mem_alloc_size + num7] = mem[n * mem_alloc_size + num7 + magic_samples[n]]; } magic_samples[n] += num6; } } } private void speex_resampler_process_native(int channel_index, ref int in_len, Span output, int output_ptr, ref int out_len) { int num = 0; int num2 = filt_len; int num3 = 0; int num4 = channel_index * mem_alloc_size; started = 1; num3 = resampler_ptr(channel_index, mem, num4, ref in_len, output, output_ptr, ref out_len); if (last_sample[channel_index] < in_len) { in_len = last_sample[channel_index]; } out_len = num3; last_sample[channel_index] -= in_len; int num5 = in_len; for (num = num4; num < num2 - 1 + num4; num++) { mem[num] = mem[num + num5]; } } private int speex_resampler_magic(int channel_index, Span output, ref int output_ptr, int out_len) { int in_len = magic_samples[channel_index]; int num = channel_index * mem_alloc_size; int num2 = filt_len; speex_resampler_process_native(channel_index, ref in_len, output, output_ptr, ref out_len); magic_samples[channel_index] -= in_len; if (magic_samples[channel_index] != 0) { for (int i = num; i < magic_samples[channel_index] + num; i++) { mem[num2 - 1 + i] = mem[num2 - 1 + i + in_len]; } } output_ptr += out_len * out_stride; return out_len; } [Obsolete("Use ResamplerFactory.CreateResampler instead")] public SpeexResampler(int nb_channels, int in_rate, int out_rate, int quality) : this(nb_channels, in_rate, out_rate, in_rate, out_rate, quality) { } [Obsolete("Use ResamplerFactory.CreateResampler instead")] public SpeexResampler(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality) { if (quality > 10 || quality < 0) { throw new ArgumentException("Quality must be between 0 and 10"); } initialised = 0; started = 0; this.in_rate = 0; this.out_rate = 0; num_rate = 0; den_rate = 0; this.quality = -1; sinc_table_length = 0; mem_alloc_size = 0; filt_len = 0; mem = null; resampler_ptr = null; cutoff = 1f; this.nb_channels = nb_channels; in_stride = 1; out_stride = 1; buffer_size = 160; last_sample = new int[nb_channels]; magic_samples = new int[nb_channels]; samp_frac_num = new int[nb_channels]; for (int i = 0; i < nb_channels; i++) { last_sample[i] = 0; magic_samples[i] = 0; samp_frac_num[i] = 0; } Quality = quality; SetRateFraction(ratio_num, ratio_den, in_rate, out_rate); update_filter(); initialised = 1; } public void Process(int channel_index, Span input, ref int in_len, Span output, ref int out_len) { Process(channel_index, input, 0, ref in_len, output, 0, ref out_len); } private void Process(int channel_index, Span input, int input_ptr, ref int in_len, Span output, int output_ptr, ref int out_len) { int num = in_len; int num2 = out_len; int num3 = channel_index * mem_alloc_size; int num4 = filt_len - 1; int num5 = mem_alloc_size - num4; int num6 = in_stride; if (magic_samples[channel_index] != 0) { num2 -= speex_resampler_magic(channel_index, output, ref output_ptr, num2); } if (magic_samples[channel_index] == 0) { while (num != 0 && num2 != 0) { int in_len2 = ((num > num5) ? num5 : num); int out_len2 = num2; if (input != null) { for (int i = 0; i < in_len2; i++) { mem[num3 + i + num4] = input[input_ptr + i * num6]; } } else { for (int i = 0; i < in_len2; i++) { mem[num3 + i + num4] = 0f; } } speex_resampler_process_native(channel_index, ref in_len2, output, output_ptr, ref out_len2); num -= in_len2; num2 -= out_len2; output_ptr += out_len2 * out_stride; if (input != null) { input_ptr += in_len2 * num6; } } } in_len -= num; out_len -= num2; } public void Process(int channel_index, Span input, ref int in_len, Span output, ref int out_len) { Process(channel_index, input, 0, ref in_len, output, 0, ref out_len); } private void Process(int channel_index, Span input, int input_ptr, ref int in_len, Span output, int output_ptr, ref int out_len) { int num = in_stride; int num2 = out_stride; int num3 = in_len; int num4 = out_len; int num5 = channel_index * mem_alloc_size; int num6 = mem_alloc_size - (filt_len - 1); int num7 = ((num4 < 8192) ? num4 : 8192); float[] array = new float[num7]; out_stride = 1; while (num3 != 0 && num4 != 0) { int output_ptr2 = 0; int in_len2 = ((num3 > num6) ? num6 : num3); int out_len2 = ((num4 > num7) ? num7 : num4); int num8 = 0; if (magic_samples[channel_index] != 0) { num8 = speex_resampler_magic(channel_index, array, ref output_ptr2, out_len2); out_len2 -= num8; num4 -= num8; } if (magic_samples[channel_index] == 0) { if (input != null) { for (int i = 0; i < in_len2; i++) { mem[num5 + i + filt_len - 1] = input[input_ptr + i * num]; } } else { for (int i = 0; i < in_len2; i++) { mem[num5 + i + filt_len - 1] = 0f; } } speex_resampler_process_native(channel_index, ref in_len2, array, output_ptr2, ref out_len2); } else { in_len2 = 0; out_len2 = 0; } for (int i = 0; i < out_len2 + num8; i++) { output[output_ptr + i * num2] = FLOAT2INT(array[i]); } num3 -= in_len2; num4 -= out_len2; output_ptr += (out_len2 + num8) * num2; if (input != null) { input_ptr += in_len2 * num; } } out_stride = num2; in_len -= num3; out_len -= num4; } public void ProcessInterleaved(Span input, ref int in_len, Span output, ref int out_len) { int num = out_len; int num2 = in_len; int num3 = in_stride; int num4 = out_stride; in_stride = (out_stride = nb_channels); for (int i = 0; i < nb_channels; i++) { out_len = num; in_len = num2; if (input != null) { Process(i, input, i, ref in_len, output, i, ref out_len); } else { Process(i, null, 0, ref in_len, output, i, ref out_len); } } in_stride = num3; out_stride = num4; } public void ProcessInterleaved(Span input, ref int in_len, Span output, ref int out_len) { int num = out_len; int num2 = in_len; int num3 = in_stride; int num4 = out_stride; in_stride = (out_stride = nb_channels); for (int i = 0; i < nb_channels; i++) { out_len = num; in_len = num2; if (input != null) { Process(i, input, i, ref in_len, output, i, ref out_len); } else { Process(i, null, 0, ref in_len, output, i, ref out_len); } } in_stride = num3; out_stride = num4; } public void SkipZeroes() { for (int i = 0; i < nb_channels; i++) { last_sample[i] = filt_len / 2; } } public void ResetMem() { for (int i = 0; i < nb_channels; i++) { last_sample[i] = 0; magic_samples[i] = 0; samp_frac_num[i] = 0; } for (int i = 0; i < nb_channels * (filt_len - 1); i++) { mem[i] = 0f; } } public void Dispose() { } public void SetRates(int in_rate, int out_rate) { SetRateFraction(in_rate, out_rate, in_rate, out_rate); } public void GetRates(out int in_rate, out int out_rate) { in_rate = this.in_rate; out_rate = this.out_rate; } public void SetRateFraction(int ratio_num, int ratio_den, int in_rate, int out_rate) { if (this.in_rate == in_rate && this.out_rate == out_rate && num_rate == ratio_num && den_rate == ratio_den) { return; } int num = den_rate; this.in_rate = in_rate; this.out_rate = out_rate; num_rate = ratio_num; den_rate = ratio_den; for (int i = 2; i <= Inlines.IMIN(num_rate, den_rate); i++) { while (num_rate % i == 0 && den_rate % i == 0) { num_rate /= i; den_rate /= i; } } if (num > 0) { for (int j = 0; j < nb_channels; j++) { samp_frac_num[j] = samp_frac_num[j] * den_rate / num; if (samp_frac_num[j] >= den_rate) { samp_frac_num[j] = den_rate - 1; } } } if (initialised != 0) { update_filter(); } } public void GetRateFraction(out int ratio_num, out int ratio_den) { ratio_num = num_rate; ratio_den = den_rate; } } } namespace Concentus.Common.CPlusPlus { internal static class Arrays { internal static T[][] InitTwoDimensionalArray(int x, int y) { T[][] array = new T[x][]; for (int i = 0; i < x; i++) { array[i] = new T[y]; } return array; } internal static Pointer> InitTwoDimensionalArrayPointer(int x, int y) { Pointer> pointer = Pointer.Malloc>(x); for (int i = 0; i < x; i++) { pointer[i] = Pointer.Malloc(y); } return pointer; } internal static T[][][] InitThreeDimensionalArray(int x, int y, int z) { T[][][] array = new T[x][][]; for (int i = 0; i < x; i++) { array[i] = new T[y][]; for (int j = 0; j < y; j++) { array[i][j] = new T[z]; } } return array; } internal static void MemSetByte(byte[] array, byte value) { MemoryExtensions.AsSpan(array).Fill(value); } internal static void MemSetInt(int[] array, int value, int length) { MemoryExtensions.AsSpan(array, 0, length).Fill(value); } internal static void MemSetShort(short[] array, short value, int length) { MemoryExtensions.AsSpan(array, 0, length).Fill(value); } internal static void MemSetFloat(float[] array, float value, int length) { MemoryExtensions.AsSpan(array, 0, length).Fill(value); } internal static void MemSetSbyte(sbyte[] array, sbyte value, int length) { MemoryExtensions.AsSpan(array, 0, length).Fill(value); } internal static void MemSetWithOffset(T[] array, T value, int offset, int length) { MemoryExtensions.AsSpan(array, offset, length).Fill(value); } internal static void MemSetWithOffset(Span array, T value, int offset, int length) { array.Slice(offset, length).Fill(value); } internal static void MemMoveByte(byte[] array, int src_idx, int dst_idx, int length) { if (src_idx != dst_idx && length != 0) { Buffer.BlockCopy(array, src_idx, array, dst_idx, length); } } internal static void MemMoveByte(Span array, int src_idx, int dst_idx, int length) { if (src_idx != dst_idx && length != 0) { array.Slice(src_idx, length).CopyTo(array.Slice(dst_idx, length)); } } internal static void MemCopy(int[] src, int src_idx, int[] dst, int dst_idx, int length) { if (length != 0) { Buffer.BlockCopy(src, src_idx * 4, dst, dst_idx * 4, length * 4); } } internal static void MemCopy(short[] src, int src_idx, short[] dst, int dst_idx, int length) { if (length != 0) { Buffer.BlockCopy(src, src_idx * 2, dst, dst_idx * 2, length * 2); } } internal static void MemCopy(sbyte[] src, int src_idx, sbyte[] dst, int dst_idx, int length) { if (length != 0) { Buffer.BlockCopy(src, src_idx, dst, dst_idx, length); } } internal static void MemMoveInt(int[] array, int src_idx, int dst_idx, int length) { if (src_idx != dst_idx && length != 0) { Buffer.BlockCopy(array, src_idx * 4, array, dst_idx * 4, length * 4); } } internal static void MemMoveShort(short[] array, int src_idx, int dst_idx, int length) { if (src_idx != dst_idx && length != 0) { Buffer.BlockCopy(array, src_idx * 2, array, dst_idx * 2, length * 2); } } } internal class BoxedValueInt { internal int Val; internal BoxedValueInt(int v = 0) { Val = v; } public override string ToString() { return Val.ToString(); } } internal class BoxedValueShort { internal short Val; internal BoxedValueShort(short v = 0) { Val = v; } public override string ToString() { return Val.ToString(); } } internal class BoxedValueSbyte { internal sbyte Val; internal BoxedValueSbyte(sbyte v = 0) { Val = v; } public override string ToString() { return Val.ToString(); } } internal class BoxedValue { internal T Val; internal BoxedValue(T v = default(T)) { Val = v; } public override string ToString() { if (Val != null) { return Val.ToString(); } return "null"; } } internal class Pointer { private const bool CHECK_UNINIT_MEM = false; private T[] _array; private int _offset; internal int Offset => _offset; internal T[] Data => _array; internal T this[int index] { get { return _array[index + _offset]; } set { _array[index + _offset] = value; } } internal T this[uint index] { get { return this[(int)index]; } set { this[(int)index] = value; } } internal Pointer(int capacity) { _array = new T[capacity]; _offset = 0; } internal Pointer(T[] buffer) { _array = buffer; _offset = 0; } internal Pointer(T[] buffer, int absoluteOffset) { _array = buffer; _offset = absoluteOffset; } internal Pointer Iterate(out T returnVal) { returnVal = _array[_offset]; return Point(1); } internal Pointer Point(int relativeOffset) { if (relativeOffset == 0) { return this; } return new Pointer(_array, _offset + relativeOffset); } internal Pointer Point(uint relativeOffset) { if (relativeOffset == 0) { return this; } return new Pointer(_array, _offset + (int)relativeOffset); } private static string invert_endianness(string hexstring) { StringBuilder stringBuilder = new StringBuilder(hexstring.Length); for (int i = 0; i < hexstring.Length / 2; i++) { stringBuilder.Append(hexstring.Substring(hexstring.Length - (i + 1) * 2, 2)); } return stringBuilder.ToString(); } private static void PrintMemCopy(E[] source, int sourceOffset, int length) { if (typeof(E) == typeof(int) || typeof(E) == typeof(uint)) { string text = string.Empty; for (int i = 0; i < length; i++) { text += invert_endianness($"{source[i + sourceOffset]:x8}"); } } else if (typeof(E) == typeof(short) || typeof(E) == typeof(ushort)) { string text2 = string.Empty; for (int j = 0; j < length; j++) { text2 += invert_endianness($"{source[j + sourceOffset]:x4}"); } } else if (typeof(E) == typeof(byte) || typeof(E) == typeof(sbyte)) { string text3 = string.Empty; for (int k = 0; k < length; k++) { text3 += invert_endianness($"{source[k + sourceOffset]:x2}"); } } } internal void MemCopyTo(Pointer destination, int length) { if (destination != null) { Array.Copy(_array, _offset, destination._array, destination.Offset, length); return; } for (int i = 0; i < length; i++) { destination[i] = _array[i + _offset]; } } internal void MemCopyTo(T[] destination, int offset, int length) { Array.Copy(_array, _offset, destination, offset, length); } internal void MemCopyFrom(T[] source, int sourceOffset, int length) { Array.Copy(source, sourceOffset, _array, _offset, length); } internal void MemSet(T value, int length) { MemSet(value, (uint)length); } internal void MemSet(T value, uint length) { for (int i = _offset; i < _offset + length; i++) { _array[i] = value; } } internal void MemMoveTo(Pointer other, int length) { if (_array == other._array) { MemMove(other.Offset - Offset, length); } else { MemCopyTo(other, length); } } internal void MemMove(int move_dist, int length) { MemoryExtensions.AsSpan(_array, _offset, length).CopyTo(MemoryExtensions.AsSpan(_array, _offset + move_dist, length)); } public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return false; } Pointer pointer = (Pointer)obj; if (pointer._offset == _offset) { return pointer._array == _array; } return false; } public override int GetHashCode() { return _array.GetHashCode() + _offset.GetHashCode(); } } internal static class Pointer { internal static Pointer Malloc(int capacity) { return new Pointer(capacity); } internal static Pointer GetPointer(this E[] memory, int offset = 0) { if (memory == null) { return null; } return new Pointer(memory, offset); } } } namespace Concentus.Celt { internal static class Bands { internal class band_ctx { internal int encode; internal CeltMode m; internal int i; internal int intensity; internal int spread; internal int tf_change; internal EntropyCoder ec; internal int remaining_bits; internal int[][] bandE; internal uint seed; } internal class split_ctx { internal int inv; internal int imid; internal int iside; internal int delta; internal int itheta; internal int qalloc; } private static readonly byte[] bit_interleave_table = new byte[16] { 0, 1, 1, 1, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3 }; private static readonly byte[] bit_deinterleave_table = new byte[16] { 0, 3, 12, 15, 48, 51, 60, 63, 192, 195, 204, 207, 240, 243, 252, 255 }; internal static int hysteresis_decision(int val, int[] thresholds, int[] hysteresis, int N, int prev) { int i; for (i = 0; i < N && val >= thresholds[i]; i++) { } if (i > prev && val < thresholds[prev] + hysteresis[prev]) { i = prev; } if (i < prev && val > thresholds[prev - 1] - hysteresis[prev - 1]) { i = prev; } return i; } internal static uint celt_lcg_rand(uint seed) { return 1664525 * seed + 1013904223; } internal static int bitexact_cos(int x) { int num = 4096 + x * x >> 13; num = 32767 - num + Inlines.FRAC_MUL16(num, -7651 + Inlines.FRAC_MUL16(num, 8277 + Inlines.FRAC_MUL16(-626, num))); return 1 + num; } internal static int bitexact_log2tan(int isin, int icos) { int num = Inlines.EC_ILOG((uint)icos); int num2 = Inlines.EC_ILOG((uint)isin); icos <<= 15 - num; isin <<= 15 - num2; return (num2 - num) * 2048 + Inlines.FRAC_MUL16(isin, Inlines.FRAC_MUL16(isin, -2597) + 7932) - Inlines.FRAC_MUL16(icos, Inlines.FRAC_MUL16(icos, -2597) + 7932); } internal static void compute_band_energies(CeltMode m, int[][] X, int[][] bandE, int end, int C, int LM) { short[] eBands = m.eBands; _ = m.shortMdctSize; int num = 0; do { for (int i = 0; i < end; i++) { int num2 = 0; int num3 = 0; num2 = Inlines.celt_maxabs32(X[num], eBands[i] << LM, eBands[i + 1] - eBands[i] << LM); if (num2 > 0) { int num4 = Inlines.celt_ilog2(num2) - 14 + ((m.logN[i] >> 3) + LM + 1 >> 1); int num5 = eBands[i] << LM; if (num4 > 0) { do { num3 = Inlines.MAC16_16(num3, Inlines.EXTRACT16(Inlines.SHR32(X[num][num5], num4)), Inlines.EXTRACT16(Inlines.SHR32(X[num][num5], num4))); } while (++num5 < eBands[i + 1] << LM); } else { do { num3 = Inlines.MAC16_16(num3, Inlines.EXTRACT16(Inlines.SHL32(X[num][num5], -num4)), Inlines.EXTRACT16(Inlines.SHL32(X[num][num5], -num4))); } while (++num5 < eBands[i + 1] << LM); } bandE[num][i] = 1 + Inlines.VSHR32(Inlines.celt_sqrt(num3), -num4); } else { bandE[num][i] = 1; } } } while (++num < C); } internal static void normalise_bands(CeltMode m, int[][] freq, int[][] X, int[][] bandE, int end, int C, int M) { short[] eBands = m.eBands; int num = 0; do { int num2 = 0; do { int num3 = Inlines.celt_zlog2(bandE[num][num2]) - 13; int b = Inlines.EXTRACT16(Inlines.celt_rcp(Inlines.SHL32(Inlines.VSHR32(bandE[num][num2], num3), 3))); int num4 = M * eBands[num2]; do { X[num][num4] = Inlines.MULT16_16_Q15(Inlines.VSHR32(freq[num][num4], num3 - 1), b); } while (++num4 < M * eBands[num2 + 1]); } while (++num2 < end); } while (++num < C); } internal static void denormalise_bands(CeltMode m, int[] X, Span freq, int freq_ptr, Span bandLogE, int bandLogE_ptr, int start, int end, int M, int downsample, int silence) { short[] eBands = m.eBands; int num = M * m.shortMdctSize; int num2 = M * eBands[end]; if (downsample != 1) { num2 = Inlines.IMIN(num2, num / downsample); } if (silence != 0) { num2 = 0; start = (end = 0); } int index = freq_ptr; int num3 = M * eBands[start]; for (int i = 0; i < M * eBands[start]; i++) { freq[index++] = 0; } for (int i = start; i < end; i++) { int num4 = M * eBands[i]; int num5 = M * eBands[i + 1]; int num6 = Inlines.ADD16(bandLogE[bandLogE_ptr + i], Inlines.SHL16(Tables.eMeans[i], 6)); int num7 = 16 - (num6 >> 10); int b; if (num7 > 31) { num7 = 0; b = 0; } else { b = Inlines.celt_exp2_frac(num6 & 0x3FF); } if (num7 < 0) { if (num7 < -2) { b = 32767; num7 = -2; } do { freq[index] = Inlines.SHR32(Inlines.MULT16_16(X[num3], b), -num7); } while (++num4 < num5); } else { do { freq[index++] = Inlines.SHR32(Inlines.MULT16_16(X[num3++], b), num7); } while (++num4 < num5); } } Arrays.MemSetWithOffset(freq, 0, freq_ptr + num2, num - num2); } internal static void anti_collapse(CeltMode m, int[][] X_, byte[] collapse_masks, int LM, int C, int size, int start, int end, int[] logE, int[] prev1logE, int[] prev2logE, int[] pulses, uint seed) { for (int i = start; i < end; i++) { int num = m.eBands[i + 1] - m.eBands[i]; int a = Inlines.celt_udiv(1 + pulses[i], m.eBands[i + 1] - m.eBands[i]) >> LM; int b = Inlines.SHR32(Inlines.celt_exp2(-Inlines.SHL16(a, 7)), 1); int a2 = Inlines.MULT16_32_Q15((short)16384, Inlines.MIN32(32767, b)); int num2 = num << LM; int num3 = Inlines.celt_ilog2(num2) >> 1; int a3 = Inlines.celt_rsqrt_norm(Inlines.SHL32(num2, 7 - num3 << 1)); int num4 = 0; do { int num5 = 0; int a4 = prev1logE[num4 * m.nbEBands + i]; int num6 = prev2logE[num4 * m.nbEBands + i]; if (C == 1) { a4 = Inlines.MAX16(a4, prev1logE[m.nbEBands + i]); num6 = Inlines.MAX16(num6, prev2logE[m.nbEBands + i]); } int b2 = Inlines.EXTEND32(logE[num4 * m.nbEBands + i]) - Inlines.EXTEND32(Inlines.MIN16(a4, num6)); b2 = Inlines.MAX32(0, b2); int b4; if (b2 < 16384) { int b3 = Inlines.SHR32(Inlines.celt_exp2((short)(-Inlines.EXTRACT16(b2))), 1); b4 = 2 * Inlines.MIN16(16383, b3); } else { b4 = 0; } if (LM == 3) { b4 = Inlines.MULT16_16_Q14(23170, Inlines.MIN32(23169, b4)); } b4 = Inlines.SHR16(Inlines.MIN16(a2, b4), 1); b4 = Inlines.SHR32(Inlines.MULT16_16_Q15(a3, b4), num3); int num7 = m.eBands[i] << LM; for (int j = 0; j < 1 << LM; j++) { if ((collapse_masks[i * C + num4] & (1 << j)) == 0) { int num8 = num7 + j; for (int k = 0; k < num; k++) { seed = celt_lcg_rand(seed); X_[num4][num8 + (k << LM)] = (((seed & 0x8000) != 0) ? b4 : (-b4)); } num5 = 1; } } if (num5 != 0) { VQ.renormalise_vector(MemoryExtensions.AsSpan(X_[num4]).Slice(num7), num << LM, 32767); } } while (++num4 < C); } } internal static void intensity_stereo(CeltMode m, Span X, int X_ptr, Span Y, int Y_ptr, int[][] bandE, int bandID, int N) { int shift = Inlines.celt_zlog2(Inlines.MAX32(bandE[0][bandID], bandE[1][bandID])) - 13; int num = Inlines.VSHR32(bandE[0][bandID], shift); int num2 = Inlines.VSHR32(bandE[1][bandID], shift); int b = 1 + Inlines.celt_sqrt(1 + Inlines.MULT16_16(num, num) + Inlines.MULT16_16(num2, num2)); int a = Inlines.DIV32_16(Inlines.SHL32(num, 14), b); int a2 = Inlines.DIV32_16(Inlines.SHL32(num2, 14), b); for (int i = 0; i < N; i++) { int b2 = X[X_ptr + i]; int b3 = Y[Y_ptr + i]; X[X_ptr + i] = Inlines.EXTRACT16(Inlines.SHR32(Inlines.MAC16_16(Inlines.MULT16_16(a, b2), a2, b3), 14)); } } private static void stereo_split(Span X, int X_ptr, Span Y, int Y_ptr, int N) { for (int i = 0; i < N; i++) { int num = Inlines.MULT16_16(23170, X[X_ptr + i]); int num2 = Inlines.MULT16_16(23170, Y[Y_ptr + i]); X[X_ptr + i] = Inlines.EXTRACT16(Inlines.SHR32(Inlines.ADD32(num, num2), 15)); Y[Y_ptr + i] = Inlines.EXTRACT16(Inlines.SHR32(Inlines.SUB32(num2, num), 15)); } } private static void stereo_merge(Span X, Span Y, int mid, int N) { Kernels.dual_inner_prod(Y, X, Y, N, out var xy, out var xy2); xy = Inlines.MULT16_32_Q15(mid, xy); int num = Inlines.SHR16(mid, 1); int num2 = Inlines.MULT16_16(num, num) + xy2 - 2 * xy; int num3 = Inlines.MULT16_16(num, num) + xy2 + 2 * xy; if (num3 < 161061 || num2 < 161061) { X.Slice(0, N).CopyTo(Y); return; } int num4 = Inlines.celt_ilog2(num2) >> 1; int num5 = Inlines.celt_ilog2(num3) >> 1; int a = Inlines.celt_rsqrt_norm(Inlines.VSHR32(num2, num4 - 7 << 1)); int a2 = Inlines.celt_rsqrt_norm(Inlines.VSHR32(num3, num5 - 7 << 1)); if (num4 < 7) { num4 = 7; } if (num5 < 7) { num5 = 7; } for (int i = 0; i < N; i++) { int a3 = Inlines.MULT16_16_P15(mid, X[i]); int b = Y[i]; X[i] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MULT16_16(a, Inlines.SUB16(a3, b)), num4 + 1)); Y[i] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MULT16_16(a2, Inlines.ADD16(a3, b)), num5 + 1)); } } internal static int spreading_decision(CeltMode m, int[][] X, ref int average, int last_decision, ref int hf_average, ref int tapset_decision, int update_hf, int end, int C, int M) { int num = 0; int num2 = 0; short[] eBands = m.eBands; int num3 = 0; if (M * (eBands[end] - eBands[end - 1]) <= 8) { return 0; } int num4 = 0; do { for (int i = 0; i < end; i++) { int num5 = 0; int[] array = new int[3]; int[] array2 = X[num4]; int num6 = M * eBands[i]; int num7 = M * (eBands[i + 1] - eBands[i]); if (num7 <= 8) { continue; } for (int j = num6; j < num7 + num6; j++) { int num8 = Inlines.MULT16_16(Inlines.MULT16_16_Q15(array2[j], array2[j]), num7); if (num8 < 2048) { array[0]++; } if (num8 < 512) { array[1]++; } if (num8 < 128) { array[2]++; } } if (i > m.nbEBands - 4) { num3 += Inlines.celt_udiv(32 * (array[1] + array[0]), num7); } num5 = ((2 * array[2] >= num7) ? 1 : 0) + ((2 * array[1] >= num7) ? 1 : 0) + ((2 * array[0] >= num7) ? 1 : 0); num += num5 * 256; num2++; } } while (++num4 < C); if (update_hf != 0) { if (num3 != 0) { num3 = Inlines.celt_udiv(num3, C * (4 - m.nbEBands + end)); } hf_average = hf_average + num3 >> 1; num3 = hf_average; if (tapset_decision == 2) { num3 += 4; } else if (tapset_decision == 0) { num3 -= 4; } if (num3 > 22) { tapset_decision = 2; } else if (num3 > 18) { tapset_decision = 1; } else { tapset_decision = 0; } } num = Inlines.celt_udiv(num, num2); num = 3 * (average = num + average >> 1) + ((3 - last_decision << 7) + 64) + 2 >> 2; if (num < 80) { return 3; } if (num < 256) { return 2; } if (num < 384) { return 1; } return 0; } internal static void deinterleave_hadamard(Span X, int X_ptr, int N0, int stride, int hadamard) { int num = N0 * stride; int[] array = new int[num]; if (hadamard != 0) { int num2 = stride - 2; for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { array[Tables.ordery_table[num2 + i] * N0 + j] = X[j * stride + i + X_ptr]; } } } else { for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { array[i * N0 + j] = X[j * stride + i + X_ptr]; } } } MemoryExtensions.AsSpan(array, 0, num).CopyTo(X.Slice(X_ptr)); } internal static void interleave_hadamard(Span X, int X_ptr, int N0, int stride, int hadamard) { int num = N0 * stride; int[] array = new int[num]; if (hadamard != 0) { int num2 = stride - 2; for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { array[j * stride + i] = X[Tables.ordery_table[num2 + i] * N0 + j + X_ptr]; } } } else { for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { array[j * stride + i] = X[i * N0 + j + X_ptr]; } } } MemoryExtensions.AsSpan(array, 0, num).CopyTo(X.Slice(X_ptr)); } internal static void haar1(Span X, int X_ptr, int N0, int stride) { N0 >>= 1; for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { int num = X_ptr + i + stride * 2 * j; int a = Inlines.MULT16_16(23170, X[num]); int b = Inlines.MULT16_16(23170, X[num + stride]); X[num] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.ADD32(a, b), 15)); X[num + stride] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.SUB32(a, b), 15)); } } } internal static void haar1ZeroOffset(int[] X, int N0, int stride) { N0 >>= 1; for (int i = 0; i < stride; i++) { for (int j = 0; j < N0; j++) { int num = i + stride * 2 * j; int a = Inlines.MULT16_16(23170, X[num]); int b = Inlines.MULT16_16(23170, X[num + stride]); X[num] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.ADD32(a, b), 15)); X[num + stride] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.SUB32(a, b), 15)); } } } internal static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo) { short[] array = new short[8] { 16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048 }; int num = 2 * N - 1; if (stereo != 0 && N == 2) { num--; } int b2 = Inlines.celt_sudiv(b + num * offset, num); b2 = Inlines.IMIN(b - pulse_cap - 32, b2); b2 = Inlines.IMIN(64, b2); if (b2 < 4) { return 1; } int num2 = array[b2 & 7] >> 14 - (b2 >> 3); return num2 + 1 >> 1 << 1; } internal static void compute_theta_decode(band_ctx ctx, split_ctx sctx, ReadOnlySpan encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int N, ref int b, int B, int B0, int LM, int stereo, ref int fill) { int num = 0; int inv = 0; CeltMode m = ctx.m; int i = ctx.i; int intensity = ctx.intensity; EntropyCoder ec = ctx.ec; _ = ctx.bandE; int num2 = m.logN[i] + LM * 8; int offset = (num2 >> 1) - ((stereo != 0 && N == 2) ? 16 : 4); int num3 = compute_qn(N, b, offset, num2, stereo); if (stereo != 0 && i >= intensity) { num3 = 1; } int num4 = (int)ec.tell_frac(); if (num3 != 1) { if (stereo != 0 && N > 2) { int num5 = 3; int num6 = num; int num7 = num3 / 2; uint ft = (uint)(num5 * (num7 + 1) + num7); int num8 = (int)ec.decode(ft); num6 = ((num8 >= (num7 + 1) * num5) ? (num7 + 1 + (num8 - (num7 + 1) * num5)) : (num8 / num5)); ec.dec_update(encodedData, (uint)((num6 <= num7) ? (num5 * num6) : (num6 - 1 - num7 + (num7 + 1) * num5)), (uint)((num6 <= num7) ? (num5 * (num6 + 1)) : (num6 - num7 + (num7 + 1) * num5)), ft); num = num6; } else if (B0 > 1 || stereo != 0) { num = (int)ec.dec_uint(encodedData, (uint)(num3 + 1)); } else { int num9 = 1; int num10 = ((num3 >> 1) + 1) * ((num3 >> 1) + 1); int num11 = 0; int num12 = (int)ec.decode((uint)num10); if (num12 < (num3 >> 1) * ((num3 >> 1) + 1) >> 1) { num = (int)(Inlines.isqrt32((uint)(8 * num12 + 1)) - 1) >> 1; num9 = num + 1; num11 = num * (num + 1) >> 1; } else { num = (int)(2 * (num3 + 1) - Inlines.isqrt32((uint)(8 * (num10 - num12 - 1) + 1))) >> 1; num9 = num3 + 1 - num; num11 = num10 - ((num3 + 1 - num) * (num3 + 2 - num) >> 1); } ec.dec_update(encodedData, (uint)num11, (uint)(num11 + num9), (uint)num10); } num = Inlines.celt_udiv(num * 16384, num3); } else if (stereo != 0) { inv = ((b > 16 && ctx.remaining_bits > 16) ? ec.dec_bit_logp(encodedData, 2u) : 0); num = 0; } int num13 = (int)ec.tell_frac() - num4; b -= num13; int num14; int num15; int delta; switch (num) { case 0: num14 = 32767; num15 = 0; fill &= (1 << B) - 1; delta = -16384; break; case 16384: num14 = 0; num15 = 32767; fill &= (1 << B) - 1 << B; delta = 16384; break; default: num14 = bitexact_cos((short)num); num15 = bitexact_cos((short)(16384 - num)); delta = Inlines.FRAC_MUL16(N - 1 << 7, bitexact_log2tan(num15, num14)); break; } sctx.inv = inv; sctx.imid = num14; sctx.iside = num15; sctx.delta = delta; sctx.itheta = num; sctx.qalloc = num13; } internal static void compute_theta_encode(band_ctx ctx, split_ctx sctx, Span encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int N, ref int b, int B, int B0, int LM, int stereo, ref int fill) { int num = 0; int num2 = 0; CeltMode m = ctx.m; int i = ctx.i; int intensity = ctx.intensity; EntropyCoder ec = ctx.ec; int[][] bandE = ctx.bandE; int num3 = m.logN[i] + LM * 8; int offset = (num3 >> 1) - ((stereo != 0 && N == 2) ? 16 : 4); int num4 = compute_qn(N, b, offset, num3, stereo); if (stereo != 0 && i >= intensity) { num4 = 1; } num = VQ.stereo_itheta(X.Slice(X_ptr), Y.Slice(Y_ptr), stereo, N); int num5 = (int)ec.tell_frac(); if (num4 != 1) { num = num * num4 + 8192 >> 14; if (stereo != 0 && N > 2) { int num6 = 3; int num7 = num; int num8 = num4 / 2; uint ft = (uint)(num6 * (num8 + 1) + num8); ec.encode(encodedData, (uint)((num7 <= num8) ? (num6 * num7) : (num7 - 1 - num8 + (num8 + 1) * num6)), (uint)((num7 <= num8) ? (num6 * (num7 + 1)) : (num7 - num8 + (num8 + 1) * num6)), ft); } else if (B0 > 1 || stereo != 0) { ec.enc_uint(encodedData, (uint)num, (uint)(num4 + 1)); } else { int num9 = 1; int num10 = ((num4 >> 1) + 1) * ((num4 >> 1) + 1); num9 = ((num <= num4 >> 1) ? (num + 1) : (num4 + 1 - num)); int num11 = ((num <= num4 >> 1) ? (num * (num + 1) >> 1) : (num10 - ((num4 + 1 - num) * (num4 + 2 - num) >> 1))); ec.encode(encodedData, (uint)num11, (uint)(num11 + num9), (uint)num10); } num = Inlines.celt_udiv(num * 16384, num4); if (stereo != 0) { if (num == 0) { intensity_stereo(m, X, X_ptr, Y, Y_ptr, bandE, i, N); } else { stereo_split(X, X_ptr, Y, Y_ptr, N); } } } else if (stereo != 0) { num2 = ((num > 8192) ? 1 : 0); if (num2 != 0) { for (int j = 0; j < N; j++) { Y[Y_ptr + j] = -Y[Y_ptr + j]; } } intensity_stereo(m, X, X_ptr, Y, Y_ptr, bandE, i, N); if (b > 16 && ctx.remaining_bits > 16) { ec.enc_bit_logp(encodedData, num2, 2u); } else { num2 = 0; } num = 0; } int num12 = (int)ec.tell_frac() - num5; b -= num12; int num13; int num14; int delta; switch (num) { case 0: num13 = 32767; num14 = 0; fill &= (1 << B) - 1; delta = -16384; break; case 16384: num13 = 0; num14 = 32767; fill &= (1 << B) - 1 << B; delta = 16384; break; default: num13 = bitexact_cos((short)num); num14 = bitexact_cos((short)(16384 - num)); delta = Inlines.FRAC_MUL16(N - 1 << 7, bitexact_log2tan(num14, num13)); break; } sctx.inv = num2; sctx.imid = num13; sctx.iside = num14; sctx.delta = delta; sctx.itheta = num; sctx.qalloc = num12; } internal static uint quant_band_n1_encode(band_ctx ctx, Span encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int b, Span lowband_out, int lowband_out_ptr) { int num = 0; Span span = X; int index = X_ptr; EntropyCoder ec = ctx.ec; int num2 = ((!Y.IsEmpty) ? 1 : 0); int num3 = 0; do { int num4 = 0; if (ctx.remaining_bits >= 8) { num4 = ((span[index] < 0) ? 1 : 0); ec.enc_bits(encodedData, (uint)num4, 1u); ctx.remaining_bits -= 8; b -= 8; } if (num != 0) { span[index] = ((num4 != 0) ? (-16384) : 16384); } span = Y; index = Y_ptr; } while (++num3 < 1 + num2); if (!lowband_out.IsEmpty) { lowband_out[lowband_out_ptr] = Inlines.SHR16(X[X_ptr], 4); } return 1u; } internal static uint quant_band_n1_decode(band_ctx ctx, ReadOnlySpan encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int b, Span lowband_out, int lowband_out_ptr) { int num = 1; Span span = X; int index = X_ptr; EntropyCoder ec = ctx.ec; int num2 = ((!Y.IsEmpty) ? 1 : 0); int num3 = 0; do { int num4 = 0; if (ctx.remaining_bits >= 8) { num4 = (int)ec.dec_bits(encodedData, 1u); ctx.remaining_bits -= 8; b -= 8; } if (num != 0) { span[index] = ((num4 != 0) ? (-16384) : 16384); } span = Y; index = Y_ptr; } while (++num3 < 1 + num2); if (!lowband_out.IsEmpty) { lowband_out[lowband_out_ptr] = Inlines.SHR16(X[X_ptr], 4); } return 1u; } internal static uint quant_partition_encode(band_ctx ctx, Span encodedData, Span X, int X_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, int gain, int fill) { int num = 0; int num2 = B; int num3 = 0; int num4 = 0; uint result = 0u; int num5 = 0; int num6 = 0; CeltMode m = ctx.m; int i = ctx.i; int spread = ctx.spread; EntropyCoder ec = ctx.ec; byte[] bits = m.cache.bits; int num7 = m.cache.index[(LM + 1) * m.nbEBands + i]; if (LM != -1 && b > bits[num7 + bits[num7]] + 12 && N > 2) { split_ctx split_ctx = new split_ctx(); int lowband_ptr2 = 0; N >>= 1; num6 = X_ptr + N; LM--; if (B == 1) { fill = (fill & 1) | (fill << 1); } B = B + 1 >> 1; compute_theta_encode(ctx, split_ctx, encodedData, X, X_ptr, X, num6, N, ref b, B, num2, LM, 0, ref fill); num = split_ctx.imid; int iside = split_ctx.iside; int num8 = split_ctx.delta; int itheta = split_ctx.itheta; int qalloc = split_ctx.qalloc; num3 = num; num4 = iside; if (num2 > 1 && (itheta & 0x3FFF) != 0) { num8 = ((itheta <= 8192) ? Inlines.IMIN(0, num8 + (N << 3 >> 5 - LM)) : (num8 - (num8 >> 4 - LM))); } int num9 = Inlines.IMAX(0, Inlines.IMIN(b, (b - num8) / 2)); int num10 = b - num9; ctx.remaining_bits -= qalloc; if (!lowband.IsEmpty) { lowband_ptr2 = lowband_ptr + N; } int remaining_bits = ctx.remaining_bits; if (num9 >= num10) { result = quant_partition_encode(ctx, encodedData, X, X_ptr, N, num9, B, lowband, lowband_ptr, LM, Inlines.MULT16_16_P15(gain, num3), fill); remaining_bits = num9 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 0) { num10 += remaining_bits - 24; } result |= quant_partition_encode(ctx, encodedData, X, num6, N, num10, B, lowband, lowband_ptr2, LM, Inlines.MULT16_16_P15(gain, num4), fill >> B) << (num2 >> 1); } else { result = quant_partition_encode(ctx, encodedData, X, num6, N, num10, B, lowband, lowband_ptr2, LM, Inlines.MULT16_16_P15(gain, num4), fill >> B) << (num2 >> 1); remaining_bits = num10 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 16384) { num9 += remaining_bits - 24; } result |= quant_partition_encode(ctx, encodedData, X, X_ptr, N, num9, B, lowband, lowband_ptr, LM, Inlines.MULT16_16_P15(gain, num3), fill); } } else { int num11 = Rate.bits2pulses(m, i, LM, b); int num12 = Rate.pulses2bits(m, i, LM, num11); ctx.remaining_bits -= num12; while (ctx.remaining_bits < 0 && num11 > 0) { ctx.remaining_bits += num12; num11--; num12 = Rate.pulses2bits(m, i, LM, num11); ctx.remaining_bits -= num12; } if (num11 != 0) { int k = Rate.get_pulses(num11); result = VQ.alg_quant(X, X_ptr, N, k, spread, B, ec, encodedData); } else if (num5 != 0) { uint num13 = (uint)((int)(1L << B) - 1); fill &= (int)num13; if (fill == 0) { Arrays.MemSetWithOffset(X, 0, X_ptr, N); } else { if (lowband.IsEmpty) { for (int j = 0; j < N; j++) { ctx.seed = celt_lcg_rand(ctx.seed); X[X_ptr + j] = (int)ctx.seed >> 20; } result = num13; } else { for (int j = 0; j < N; j++) { ctx.seed = celt_lcg_rand(ctx.seed); int num14 = 4; num14 = (((ctx.seed & 0x8000) != 0) ? num14 : (-num14)); X[X_ptr + j] = lowband[lowband_ptr + j] + num14; } result = (uint)fill; } VQ.renormalise_vector(X.Slice(X_ptr), N, gain); } } } return result; } internal static uint quant_partition_decode(band_ctx ctx, ReadOnlySpan encodedData, Span X, int X_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, int gain, int fill) { int num = 0; int num2 = B; int num3 = 0; int num4 = 0; uint result = 0u; int num5 = 1; int num6 = 0; CeltMode m = ctx.m; int i = ctx.i; int spread = ctx.spread; EntropyCoder ec = ctx.ec; byte[] bits = m.cache.bits; int num7 = m.cache.index[(LM + 1) * m.nbEBands + i]; if (LM != -1 && b > bits[num7 + bits[num7]] + 12 && N > 2) { split_ctx split_ctx = new split_ctx(); int lowband_ptr2 = 0; N >>= 1; num6 = X_ptr + N; LM--; if (B == 1) { fill = (fill & 1) | (fill << 1); } B = B + 1 >> 1; compute_theta_decode(ctx, split_ctx, encodedData, X, X_ptr, X, num6, N, ref b, B, num2, LM, 0, ref fill); num = split_ctx.imid; int iside = split_ctx.iside; int num8 = split_ctx.delta; int itheta = split_ctx.itheta; int qalloc = split_ctx.qalloc; num3 = num; num4 = iside; if (num2 > 1 && (itheta & 0x3FFF) != 0) { num8 = ((itheta <= 8192) ? Inlines.IMIN(0, num8 + (N << 3 >> 5 - LM)) : (num8 - (num8 >> 4 - LM))); } int num9 = Inlines.IMAX(0, Inlines.IMIN(b, (b - num8) / 2)); int num10 = b - num9; ctx.remaining_bits -= qalloc; if (!lowband.IsEmpty) { lowband_ptr2 = lowband_ptr + N; } int remaining_bits = ctx.remaining_bits; if (num9 >= num10) { result = quant_partition_decode(ctx, encodedData, X, X_ptr, N, num9, B, lowband, lowband_ptr, LM, Inlines.MULT16_16_P15(gain, num3), fill); remaining_bits = num9 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 0) { num10 += remaining_bits - 24; } result |= quant_partition_decode(ctx, encodedData, X, num6, N, num10, B, lowband, lowband_ptr2, LM, Inlines.MULT16_16_P15(gain, num4), fill >> B) << (num2 >> 1); } else { result = quant_partition_decode(ctx, encodedData, X, num6, N, num10, B, lowband, lowband_ptr2, LM, Inlines.MULT16_16_P15(gain, num4), fill >> B) << (num2 >> 1); remaining_bits = num10 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 16384) { num9 += remaining_bits - 24; } result |= quant_partition_decode(ctx, encodedData, X, X_ptr, N, num9, B, lowband, lowband_ptr, LM, Inlines.MULT16_16_P15(gain, num3), fill); } } else { int num11 = Rate.bits2pulses(m, i, LM, b); int num12 = Rate.pulses2bits(m, i, LM, num11); ctx.remaining_bits -= num12; while (ctx.remaining_bits < 0 && num11 > 0) { ctx.remaining_bits += num12; num11--; num12 = Rate.pulses2bits(m, i, LM, num11); ctx.remaining_bits -= num12; } if (num11 != 0) { int k = Rate.get_pulses(num11); result = VQ.alg_unquant(X, X_ptr, N, k, spread, B, ec, encodedData, gain); } else if (num5 != 0) { uint num13 = (uint)((int)(1L << B) - 1); fill &= (int)num13; if (fill == 0) { Arrays.MemSetWithOffset(X, 0, X_ptr, N); } else { if (lowband.IsEmpty) { for (int j = 0; j < N; j++) { ctx.seed = celt_lcg_rand(ctx.seed); X[X_ptr + j] = (int)ctx.seed >> 20; } result = num13; } else { for (int j = 0; j < N; j++) { ctx.seed = celt_lcg_rand(ctx.seed); int num14 = 4; num14 = (((ctx.seed & 0x8000) != 0) ? num14 : (-num14)); X[X_ptr + j] = lowband[lowband_ptr + j] + num14; } result = (uint)fill; } VQ.renormalise_vector(X.Slice(X_ptr), N, gain); } } } return result; } internal static uint quant_band_encode(band_ctx ctx, Span encodedData, Span X, int X_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, Span lowband_out, int lowband_out_ptr, int gain, Span lowband_scratch, int lowband_scratch_ptr, int fill) { int n = N; int num = B; int num2 = 0; int num3 = 0; uint num4 = 0u; int num5 = 1; int num6 = ctx.tf_change; int hadamard = ((num == 1) ? 1 : 0); n = Inlines.celt_udiv(n, B); if (N == 1) { return quant_band_n1_encode(ctx, encodedData, X, X_ptr, null, 0, b, lowband_out, lowband_out_ptr); } if (num6 > 0) { num3 = num6; } if (!lowband_scratch.IsEmpty && !lowband.IsEmpty && (num3 != 0 || ((n & 1) == 0 && num6 < 0) || num > 1)) { lowband.Slice(lowband_ptr, N).CopyTo(lowband_scratch.Slice(lowband_scratch_ptr, N)); lowband = lowband_scratch; lowband_ptr = lowband_scratch_ptr; } for (int i = 0; i < num3; i++) { haar1(X, X_ptr, N >> i, 1 << i); if (!lowband.IsEmpty) { haar1(lowband, lowband_ptr, N >> i, 1 << i); } fill = bit_interleave_table[fill & 0xF] | (bit_interleave_table[fill >> 4] << 2); } B >>= num3; n <<= num3; while ((n & 1) == 0 && num6 < 0) { haar1(X, X_ptr, n, B); if (!lowband.IsEmpty) { haar1(lowband, lowband_ptr, n, B); } fill |= fill << B; B <<= 1; n >>= 1; num2++; num6++; } num = B; int num7 = n; if (num > 1) { deinterleave_hadamard(X, X_ptr, n >> num3, num << num3, hadamard); if (!lowband.IsEmpty) { deinterleave_hadamard(lowband, lowband_ptr, n >> num3, num << num3, hadamard); } } num4 = quant_partition_encode(ctx, encodedData, X, X_ptr, N, b, B, lowband, lowband_ptr, LM, gain, fill); if (num5 != 0) { if (num > 1) { interleave_hadamard(X, X_ptr, n >> num3, num << num3, hadamard); } n = num7; B = num; for (int i = 0; i < num2; i++) { B >>= 1; n <<= 1; num4 |= num4 >> B; haar1(X, X_ptr, n, B); } for (int i = 0; i < num3; i++) { num4 = bit_deinterleave_table[num4]; haar1(X, X_ptr, N >> i, 1 << i); } B <<= num3; if (!lowband_out.IsEmpty) { int a = Inlines.celt_sqrt(Inlines.SHL32(N, 22)); for (int j = 0; j < N; j++) { lowband_out[lowband_out_ptr + j] = Inlines.MULT16_16_Q15(a, X[X_ptr + j]); } } num4 &= (uint)((1 << B) - 1); } return num4; } internal static uint quant_band_decode(band_ctx ctx, ReadOnlySpan encodedData, Span X, int X_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, Span lowband_out, int lowband_out_ptr, int gain, Span lowband_scratch, int lowband_scratch_ptr, int fill) { int n = N; int num = B; int num2 = 0; int num3 = 0; uint num4 = 0u; int num5 = 1; int num6 = ctx.tf_change; int hadamard = ((num == 1) ? 1 : 0); n = Inlines.celt_udiv(n, B); if (N == 1) { return quant_band_n1_decode(ctx, encodedData, X, X_ptr, null, 0, b, lowband_out, lowband_out_ptr); } if (num6 > 0) { num3 = num6; } if (!lowband_scratch.IsEmpty && !lowband.IsEmpty && (num3 != 0 || ((n & 1) == 0 && num6 < 0) || num > 1)) { lowband.Slice(lowband_ptr, N).CopyTo(lowband_scratch.Slice(lowband_scratch_ptr, N)); lowband = lowband_scratch; lowband_ptr = lowband_scratch_ptr; } for (int i = 0; i < num3; i++) { if (!lowband.IsEmpty) { haar1(lowband, lowband_ptr, N >> i, 1 << i); } fill = bit_interleave_table[fill & 0xF] | (bit_interleave_table[fill >> 4] << 2); } B >>= num3; n <<= num3; while ((n & 1) == 0 && num6 < 0) { if (!lowband.IsEmpty) { haar1(lowband, lowband_ptr, n, B); } fill |= fill << B; B <<= 1; n >>= 1; num2++; num6++; } num = B; int num7 = n; if (num > 1 && !lowband.IsEmpty) { deinterleave_hadamard(lowband, lowband_ptr, n >> num3, num << num3, hadamard); } num4 = quant_partition_decode(ctx, encodedData, X, X_ptr, N, b, B, lowband, lowband_ptr, LM, gain, fill); if (num5 != 0) { if (num > 1) { interleave_hadamard(X, X_ptr, n >> num3, num << num3, hadamard); } n = num7; B = num; for (int i = 0; i < num2; i++) { B >>= 1; n <<= 1; num4 |= num4 >> B; haar1(X, X_ptr, n, B); } for (int i = 0; i < num3; i++) { num4 = bit_deinterleave_table[num4]; haar1(X, X_ptr, N >> i, 1 << i); } B <<= num3; if (!lowband_out.IsEmpty) { int a = Inlines.celt_sqrt(Inlines.SHL32(N, 22)); for (int j = 0; j < N; j++) { lowband_out[lowband_out_ptr + j] = Inlines.MULT16_16_Q15(a, X[X_ptr + j]); } } num4 &= (uint)((1 << B) - 1); } return num4; } internal static uint quant_band_stereo_encode(band_ctx ctx, Span encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, Span lowband_out, int lowband_out_ptr, Span lowband_scratch, int lowband_scratch_ptr, int fill) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; uint num5 = 0u; int num6 = 0; split_ctx split_ctx = new split_ctx(); EntropyCoder ec = ctx.ec; if (N == 1) { return quant_band_n1_encode(ctx, encodedData, X, X_ptr, Y, Y_ptr, b, lowband_out, lowband_out_ptr); } int fill2 = fill; compute_theta_encode(ctx, split_ctx, encodedData, X, X_ptr, Y, Y_ptr, N, ref b, B, B, LM, 1, ref fill); num2 = split_ctx.inv; num = split_ctx.imid; int iside = split_ctx.iside; int delta = split_ctx.delta; int itheta = split_ctx.itheta; int qalloc = split_ctx.qalloc; num3 = num; num4 = iside; if (N == 2) { int num7 = 0; int num8 = b; int num9 = 0; if (itheta != 0 && itheta != 16384) { num9 = 8; } num8 -= num9; bool num10 = itheta > 8192; ctx.remaining_bits -= qalloc + num9; Span x; int num11; Span span; if (num10) { x = Y; num11 = Y_ptr; span = X; } else { x = X; num11 = X_ptr; span = Y; } if (num9 != 0) { num7 = ((x[num11] * span[Y_ptr + 1] - x[num11 + 1] * span[Y_ptr] < 0) ? 1 : 0); ec.enc_bits(encodedData, (uint)num7, 1u); } num7 = 1 - 2 * num7; num5 = quant_band_encode(ctx, encodedData, x, num11, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill2); span[Y_ptr] = -num7 * x[num11 + 1]; span[Y_ptr + 1] = num7 * x[num11]; if (num6 != 0) { X[X_ptr] = Inlines.MULT16_16_Q15(num3, X[X_ptr]); X[X_ptr + 1] = Inlines.MULT16_16_Q15(num3, X[X_ptr + 1]); Y[Y_ptr] = Inlines.MULT16_16_Q15(num4, Y[Y_ptr]); Y[Y_ptr + 1] = Inlines.MULT16_16_Q15(num4, Y[Y_ptr + 1]); int a = X[X_ptr]; X[X_ptr] = Inlines.SUB16(a, Y[Y_ptr]); Y[Y_ptr] = Inlines.ADD16(a, Y[Y_ptr]); a = X[X_ptr + 1]; X[X_ptr + 1] = Inlines.SUB16(a, Y[Y_ptr + 1]); Y[Y_ptr + 1] = Inlines.ADD16(a, Y[Y_ptr + 1]); } } else { int num8 = Inlines.IMAX(0, Inlines.IMIN(b, (b - delta) / 2)); int num9 = b - num8; ctx.remaining_bits -= qalloc; int remaining_bits = ctx.remaining_bits; if (num8 >= num9) { num5 = quant_band_encode(ctx, encodedData, X, X_ptr, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill); remaining_bits = num8 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 0) { num9 += remaining_bits - 24; } num5 |= quant_band_encode(ctx, encodedData, Y, Y_ptr, N, num9, B, null, 0, LM, null, 0, num4, null, 0, fill >> B); } else { num5 = quant_band_encode(ctx, encodedData, Y, Y_ptr, N, num9, B, null, 0, LM, null, 0, num4, null, 0, fill >> B); remaining_bits = num9 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 16384) { num8 += remaining_bits - 24; } num5 |= quant_band_encode(ctx, encodedData, X, X_ptr, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill); } } if (num6 != 0) { if (N != 2) { stereo_merge(X.Slice(X_ptr), Y.Slice(Y_ptr), num3, N); } if (num2 != 0) { for (int i = Y_ptr; i < N + Y_ptr; i++) { Y[i] = (short)(-Y[i]); } } } return num5; } internal static uint quant_band_stereo_decode(band_ctx ctx, ReadOnlySpan encodedData, Span X, int X_ptr, Span Y, int Y_ptr, int N, int b, int B, Span lowband, int lowband_ptr, int LM, Span lowband_out, int lowband_out_ptr, Span lowband_scratch, int lowband_scratch_ptr, int fill) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; uint num5 = 0u; int num6 = 1; split_ctx split_ctx = new split_ctx(); EntropyCoder ec = ctx.ec; if (N == 1) { return quant_band_n1_decode(ctx, encodedData, X, X_ptr, Y, Y_ptr, b, lowband_out, lowband_out_ptr); } int fill2 = fill; compute_theta_decode(ctx, split_ctx, encodedData, X, X_ptr, Y, Y_ptr, N, ref b, B, B, LM, 1, ref fill); num2 = split_ctx.inv; num = split_ctx.imid; int iside = split_ctx.iside; int delta = split_ctx.delta; int itheta = split_ctx.itheta; int qalloc = split_ctx.qalloc; num3 = num; num4 = iside; if (N == 2) { int num7 = 0; int num8 = b; int num9 = 0; if (itheta != 0 && itheta != 16384) { num9 = 8; } num8 -= num9; bool num10 = itheta > 8192; ctx.remaining_bits -= qalloc + num9; Span x; int num11; Span span; if (num10) { x = Y; num11 = Y_ptr; span = X; } else { x = X; num11 = X_ptr; span = Y; } if (num9 != 0) { num7 = (int)ec.dec_bits(encodedData, 1u); } num7 = 1 - 2 * num7; num5 = quant_band_decode(ctx, encodedData, x, num11, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill2); span[Y_ptr] = -num7 * x[num11 + 1]; span[Y_ptr + 1] = num7 * x[num11]; if (num6 != 0) { X[X_ptr] = Inlines.MULT16_16_Q15(num3, X[X_ptr]); X[X_ptr + 1] = Inlines.MULT16_16_Q15(num3, X[X_ptr + 1]); Y[Y_ptr] = Inlines.MULT16_16_Q15(num4, Y[Y_ptr]); Y[Y_ptr + 1] = Inlines.MULT16_16_Q15(num4, Y[Y_ptr + 1]); int a = X[X_ptr]; X[X_ptr] = Inlines.SUB16(a, Y[Y_ptr]); Y[Y_ptr] = Inlines.ADD16(a, Y[Y_ptr]); a = X[X_ptr + 1]; X[X_ptr + 1] = Inlines.SUB16(a, Y[Y_ptr + 1]); Y[Y_ptr + 1] = Inlines.ADD16(a, Y[Y_ptr + 1]); } } else { int num8 = Inlines.IMAX(0, Inlines.IMIN(b, (b - delta) / 2)); int num9 = b - num8; ctx.remaining_bits -= qalloc; int remaining_bits = ctx.remaining_bits; if (num8 >= num9) { num5 = quant_band_decode(ctx, encodedData, X, X_ptr, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill); remaining_bits = num8 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 0) { num9 += remaining_bits - 24; } num5 |= quant_band_decode(ctx, encodedData, Y, Y_ptr, N, num9, B, null, 0, LM, null, 0, num4, null, 0, fill >> B); } else { num5 = quant_band_decode(ctx, encodedData, Y, Y_ptr, N, num9, B, null, 0, LM, null, 0, num4, null, 0, fill >> B); remaining_bits = num9 - (remaining_bits - ctx.remaining_bits); if (remaining_bits > 24 && itheta != 16384) { num8 += remaining_bits - 24; } num5 |= quant_band_decode(ctx, encodedData, X, X_ptr, N, num8, B, lowband, lowband_ptr, LM, lowband_out, lowband_out_ptr, 32767, lowband_scratch, lowband_scratch_ptr, fill); } } if (num6 != 0) { if (N != 2) { stereo_merge(X.Slice(X_ptr), Y.Slice(Y_ptr), num3, N); } if (num2 != 0) { for (int i = Y_ptr; i < N + Y_ptr; i++) { Y[i] = (short)(-Y[i]); } } } return num5; } internal static void quant_all_bands_encode(int encode, CeltMode m, int start, int end, int[] X_, int[] Y_, byte[] collapse_masks, int[][] bandE, int[] pulses, int shortBlocks, int spread, int dual_stereo, int intensity, int[] tf_res, int total_bits, int balance, EntropyCoder ec, Span encodedData, int LM, int codedBands, ref uint seed) { short[] eBands = m.eBands; int num = 1; int num2 = ((Y_ == null) ? 1 : 2); int num3 = ((encode == 0) ? 1 : 0); band_ctx band_ctx = new band_ctx(); int num4 = 1 << LM; int num5 = ((shortBlocks == 0) ? 1 : num4); int num6 = num4 * eBands[start]; int[] array = new int[num2 * (num4 * eBands[m.nbEBands - 1] - num6)]; int num7 = num4 * eBands[m.nbEBands - 1] - num6; int[] array2 = X_; int lowband_scratch_ptr = num4 * eBands[m.nbEBands - 1]; int num8 = 0; band_ctx.bandE = bandE; band_ctx.ec = ec; band_ctx.encode = encode; band_ctx.intensity = intensity; band_ctx.m = m; band_ctx.seed = seed; band_ctx.spread = spread; for (int i = start; i < end; i++) { int num9 = -1; int num10 = 0; int num11 = 0; band_ctx.i = i; int num12 = ((i == end - 1) ? 1 : 0); int[] array3 = X_; int x_ptr = num4 * eBands[i]; int[] array4; if (Y_ != null) { array4 = Y_; num10 = num4 * eBands[i]; } else { array4 = null; } int num13 = num4 * eBands[i + 1] - num4 * eBands[i]; int num14 = (int)ec.tell_frac(); if (i != start) { balance -= num14; } int num15 = (band_ctx.remaining_bits = total_bits - num14 - 1); int num17; if (i <= codedBands - 1) { int num16 = Inlines.celt_sudiv(balance, Inlines.IMIN(3, codedBands - i)); num17 = Inlines.IMAX(0, Inlines.IMIN(16383, Inlines.IMIN(num15 + 1, pulses[i] + num16))); } else { num17 = 0; } if (num3 != 0 && num4 * eBands[i] - num13 >= num4 * eBands[start] && (num != 0 || num8 == 0)) { num8 = i; } num11 = (band_ctx.tf_change = tf_res[i]); if (i >= m.effEBands) { array3 = array; x_ptr = 0; if (Y_ != null) { array4 = array; num10 = 0; } array2 = null; } if (i == end - 1) { array2 = null; } uint num20; uint num21; if (num8 != 0 && (spread != 3 || num5 > 1 || num11 < 0)) { num9 = Inlines.IMAX(0, num4 * eBands[num8] - num6 - num13); int num18 = num8; while (num4 * eBands[--num18] > num9 + num6) { } int num19 = num8 - 1; while (num4 * eBands[++num19] < num9 + num6 + num13) { } num20 = (num21 = 0u); int num22 = num18; do { num20 |= collapse_masks[num22 * num2]; num21 |= collapse_masks[num22 * num2 + num2 - 1]; } while (++num22 < num19); } else { num20 = (num21 = (uint)((1 << num5) - 1)); } if (dual_stereo != 0 && i == intensity) { dual_stereo = 0; if (num3 != 0) { for (int j = 0; j < num4 * eBands[i] - num6; j++) { array[j] = Inlines.HALF32(array[j] + array[num7 + j]); } } } if (dual_stereo != 0) { num20 = quant_band_encode(band_ctx, encodedData, array3, x_ptr, num13, num17 / 2, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, 32767, array2, lowband_scratch_ptr, (int)num20); num21 = quant_band_encode(band_ctx, encodedData, array4, num10, num13, num17 / 2, num5, (num9 != -1) ? array : null, num7 + num9, LM, (num12 != 0) ? null : array, num7 + (num4 * eBands[i] - num6), 32767, array2, lowband_scratch_ptr, (int)num21); } else { num20 = ((array4 == null) ? quant_band_encode(band_ctx, encodedData, array3, x_ptr, num13, num17, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, 32767, array2, lowband_scratch_ptr, (int)(num20 | num21)) : quant_band_stereo_encode(band_ctx, encodedData, array3, x_ptr, array4, num10, num13, num17, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, array2, lowband_scratch_ptr, (int)(num20 | num21))); num21 = num20; } collapse_masks[i * num2] = (byte)(num20 & 0xFF); collapse_masks[i * num2 + num2 - 1] = (byte)(num21 & 0xFF); balance += pulses[i] + num14; num = ((num17 > num13 << 3) ? 1 : 0); } seed = band_ctx.seed; } internal static void quant_all_bands_decode(int encode, CeltMode m, int start, int end, int[] X_, int[] Y_, byte[] collapse_masks, int[][] bandE, int[] pulses, int shortBlocks, int spread, int dual_stereo, int intensity, int[] tf_res, int total_bits, int balance, EntropyCoder ec, ReadOnlySpan encodedData, int LM, int codedBands, ref uint seed) { short[] eBands = m.eBands; int num = 1; int num2 = ((Y_ == null) ? 1 : 2); int num3 = ((encode == 0) ? 1 : 0); band_ctx band_ctx = new band_ctx(); int num4 = 1 << LM; int num5 = ((shortBlocks == 0) ? 1 : num4); int num6 = num4 * eBands[start]; int[] array = new int[num2 * (num4 * eBands[m.nbEBands - 1] - num6)]; int num7 = num4 * eBands[m.nbEBands - 1] - num6; int[] array2 = X_; int lowband_scratch_ptr = num4 * eBands[m.nbEBands - 1]; int num8 = 0; band_ctx.bandE = bandE; band_ctx.ec = ec; band_ctx.encode = encode; band_ctx.intensity = intensity; band_ctx.m = m; band_ctx.seed = seed; band_ctx.spread = spread; for (int i = start; i < end; i++) { int num9 = -1; int num10 = 0; int num11 = 0; band_ctx.i = i; int num12 = ((i == end - 1) ? 1 : 0); int[] array3 = X_; int x_ptr = num4 * eBands[i]; int[] array4; if (Y_ != null) { array4 = Y_; num10 = num4 * eBands[i]; } else { array4 = null; } int num13 = num4 * eBands[i + 1] - num4 * eBands[i]; int num14 = (int)ec.tell_frac(); if (i != start) { balance -= num14; } int num15 = (band_ctx.remaining_bits = total_bits - num14 - 1); int num17; if (i <= codedBands - 1) { int num16 = Inlines.celt_sudiv(balance, Inlines.IMIN(3, codedBands - i)); num17 = Inlines.IMAX(0, Inlines.IMIN(16383, Inlines.IMIN(num15 + 1, pulses[i] + num16))); } else { num17 = 0; } if (num3 != 0 && num4 * eBands[i] - num13 >= num4 * eBands[start] && (num != 0 || num8 == 0)) { num8 = i; } num11 = (band_ctx.tf_change = tf_res[i]); if (i >= m.effEBands) { array3 = array; x_ptr = 0; if (Y_ != null) { array4 = array; num10 = 0; } array2 = null; } if (i == end - 1) { array2 = null; } uint num20; uint num21; if (num8 != 0 && (spread != 3 || num5 > 1 || num11 < 0)) { num9 = Inlines.IMAX(0, num4 * eBands[num8] - num6 - num13); int num18 = num8; while (num4 * eBands[--num18] > num9 + num6) { } int num19 = num8 - 1; while (num4 * eBands[++num19] < num9 + num6 + num13) { } num20 = (num21 = 0u); int num22 = num18; do { num20 |= collapse_masks[num22 * num2]; num21 |= collapse_masks[num22 * num2 + num2 - 1]; } while (++num22 < num19); } else { num20 = (num21 = (uint)((1 << num5) - 1)); } if (dual_stereo != 0 && i == intensity) { dual_stereo = 0; if (num3 != 0) { for (int j = 0; j < num4 * eBands[i] - num6; j++) { array[j] = Inlines.HALF32(array[j] + array[num7 + j]); } } } if (dual_stereo != 0) { num20 = quant_band_decode(band_ctx, encodedData, array3, x_ptr, num13, num17 / 2, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, 32767, array2, lowband_scratch_ptr, (int)num20); num21 = quant_band_decode(band_ctx, encodedData, array4, num10, num13, num17 / 2, num5, (num9 != -1) ? array : null, num7 + num9, LM, (num12 != 0) ? null : array, num7 + (num4 * eBands[i] - num6), 32767, array2, lowband_scratch_ptr, (int)num21); } else { num20 = ((array4 == null) ? quant_band_decode(band_ctx, encodedData, array3, x_ptr, num13, num17, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, 32767, array2, lowband_scratch_ptr, (int)(num20 | num21)) : quant_band_stereo_decode(band_ctx, encodedData, array3, x_ptr, array4, num10, num13, num17, num5, (num9 != -1) ? array : null, num9, LM, (num12 != 0) ? null : array, num4 * eBands[i] - num6, array2, lowband_scratch_ptr, (int)(num20 | num21))); num21 = num20; } collapse_masks[i * num2] = (byte)(num20 & 0xFF); collapse_masks[i * num2 + num2 - 1] = (byte)(num21 & 0xFF); balance += pulses[i] + num14; num = ((num17 > num13 << 3) ? 1 : 0); } seed = band_ctx.seed; } } internal class CeltCommon { private static readonly byte[] inv_table = new byte[128] { 255, 255, 156, 110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2 }; private static readonly short[][] gains = new short[3][] { new short[3] { 10048, 7112, 4248 }, new short[3] { 15200, 8784, 0 }, new short[3] { 26208, 3280, 0 } }; private static readonly sbyte[][] tf_select_table = new sbyte[4][] { new sbyte[8] { 0, -1, 0, -1, 0, -1, 0, -1 }, new sbyte[8] { 0, -1, 0, -2, 1, 0, 1, -1 }, new sbyte[8] { 0, -2, 0, -3, 2, 0, 1, -1 }, new sbyte[8] { 0, -2, 0, -3, 3, 0, 1, -1 } }; internal static int compute_vbr(CeltMode mode, AnalysisInfo analysis, int base_target, int LM, int bitrate, int lastCodedBands, int C, int intensity, int constrained_vbr, int stereo_saving, int tot_boost, int tf_estimate, int pitch_change, int maxDepth, OpusFramesize variable_duration, int lfe, int has_surround_mask, int surround_masking, int temporal_vbr) { int nbEBands = mode.nbEBands; short[] eBands = mode.eBands; int num = ((lastCodedBands != 0) ? lastCodedBands : nbEBands); int num2 = eBands[num] << LM; if (C == 2) { num2 += eBands[Inlines.IMIN(intensity, num)] << LM; } int num3 = base_target; if (analysis.valid != 0 && (double)analysis.activity < 0.4) { num3 -= (int)((float)(num2 << 3) * (0.4f - analysis.activity)); } if (C == 2) { int num4 = Inlines.IMIN(intensity, num); int num5 = (eBands[num4] << LM) - num4; int a = Inlines.DIV32_16(Inlines.MULT16_16(26214, num5), num2); stereo_saving = Inlines.MIN16(stereo_saving, 256); num3 -= Inlines.MIN32(Inlines.MULT16_32_Q15(a, num3), Inlines.SHR32(Inlines.MULT16_16(stereo_saving - 26, num5 << 3), 8)); } num3 += tot_boost - (16 << LM); int num6 = ((variable_duration == OpusFramesize.OPUS_FRAMESIZE_VARIABLE) ? 328 : 655); num3 += Inlines.SHL32(Inlines.MULT16_32_Q15(tf_estimate - num6, num3), 1); if (analysis.valid != 0 && lfe == 0) { float num7 = Inlines.MAX16(0f, analysis.tonality - 0.15f) - 0.09f; int num8 = num3 + (int)((float)(num2 << 3) * 1.2f * num7); if (pitch_change != 0) { num8 += (int)((float)(num2 << 3) * 0.8f); } num3 = num8; } if (has_surround_mask != 0 && lfe == 0) { int b = num3 + Inlines.SHR32(Inlines.MULT16_16(surround_masking, num2 << 3), 10); num3 = Inlines.IMAX(num3 / 4, b); } int num9 = eBands[nbEBands - 2] << LM; int a2 = Inlines.SHR32(Inlines.MULT16_16(C * num9 << 3, maxDepth), 10); a2 = Inlines.IMAX(a2, num3 >> 2); num3 = Inlines.IMIN(num3, a2); if ((has_surround_mask == 0 || lfe != 0) && (constrained_vbr != 0 || bitrate < 64000)) { int a3 = Inlines.MAX16(0, bitrate - 32000); if (constrained_vbr != 0) { a3 = Inlines.MIN16(a3, 21955); } num3 = base_target + Inlines.MULT16_32_Q15(a3, num3 - base_target); } if (has_surround_mask == 0 && tf_estimate < 3277) { int b2 = Inlines.MULT16_16_Q15(3329, Inlines.IMAX(0, Inlines.IMIN(32000, 96000 - bitrate))); int a4 = Inlines.SHR32(Inlines.MULT16_16(temporal_vbr, b2), 10); num3 += Inlines.MULT16_32_Q15(a4, num3); } return Inlines.IMIN(2 * base_target, num3); } internal static int transient_analysis(int[][] input, int len, int C, out int tf_estimate, out int tf_chan) { int num = 0; tf_chan = 0; int[] array = new int[len]; int num2 = len / 2; for (int i = 0; i < C; i++) { int num3 = 0; int a = 0; int num4 = 0; for (int j = 0; j < len; j++) { int num5 = Inlines.SHR32(input[i][j], 12); int num6 = Inlines.ADD32(a, num5); a = num4 + num6 - Inlines.SHL32(num5, 1); num4 = num5 - Inlines.SHR32(num6, 1); array[j] = Inlines.EXTRACT16(Inlines.SHR32(num6, 2)); } Arrays.MemSetInt(array, 0, 12); int num7 = 0; num7 = 14 - Inlines.celt_ilog2(1 + Inlines.celt_maxabs32(array, 0, len)); if (num7 != 0) { for (int j = 0; j < len; j++) { array[j] = Inlines.SHL16(array[j], num7); } } int num8 = 0; a = 0; for (int j = 0; j < num2; j++) { int num9 = Inlines.PSHR32(Inlines.MULT16_16(array[2 * j], array[2 * j]) + Inlines.MULT16_16(array[2 * j + 1], array[2 * j + 1]), 16); num8 += num9; array[j] = a + Inlines.PSHR32(num9 - a, 4); a = array[j]; } a = 0; int a2 = 0; for (int j = num2 - 1; j >= 0; j--) { array[j] = a + Inlines.PSHR32(array[j] - a, 3); a = array[j]; a2 = Inlines.MAX16(a2, a); } num8 = Inlines.MULT16_16(Inlines.celt_sqrt(num8), Inlines.celt_sqrt(Inlines.MULT16_16(a2, num2 >> 1))); int b = Inlines.SHL32(num2, 20) / Inlines.ADD32(1, Inlines.SHR32(num8, 1)); num3 = 0; for (int j = 12; j < num2 - 5; j += 4) { int num10 = Inlines.MAX32(0, Inlines.MIN32(127, Inlines.MULT16_32_Q15(array[j] + 1, b))); num3 += inv_table[num10]; } num3 = 64 * num3 * 4 / (6 * (num2 - 17)); if (num3 > num) { tf_chan = i; num = num3; } } bool result = num > 200; int b2 = Inlines.MAX16(0, Inlines.celt_sqrt(27 * num) - 42); tf_estimate = Inlines.celt_sqrt(Inlines.MAX32(0, Inlines.SHL32(Inlines.MULT16_16(113, Inlines.MIN16(163, b2)), 14) - 37312528)); return result ? 1 : 0; } internal static int patch_transient_decision(int[][] newE, int[][] oldE, int nbEBands, int start, int end, int C) { int a = 0; int[] array = new int[26]; if (C == 1) { array[start] = oldE[0][start]; for (int i = start + 1; i < end; i++) { array[i] = Inlines.MAX16(array[i - 1] - 1024, oldE[0][i]); } } else { array[start] = Inlines.MAX16(oldE[0][start], oldE[1][start]); for (int i = start + 1; i < end; i++) { array[i] = Inlines.MAX16(array[i - 1] - 1024, Inlines.MAX16(oldE[0][i], oldE[1][i])); } } for (int i = end - 2; i >= start; i--) { array[i] = Inlines.MAX16(array[i], array[i + 1] - 1024); } int num = 0; do { for (int i = Inlines.IMAX(2, start); i < end - 1; i++) { int a2 = Inlines.MAX16(0, newE[num][i]); int b = Inlines.MAX16(0, array[i]); a = Inlines.ADD32(a, Inlines.MAX16(0, Inlines.SUB16(a2, b))); } } while (++num < C); a = Inlines.DIV32(a, C * (end - 1 - Inlines.IMAX(2, start))); return (a > 1024) ? 1 : 0; } internal static void compute_mdcts(CeltMode mode, int shortBlocks, int[][] input, int[][] output, int C, int CC, int LM, int upsample) { int overlap = mode.overlap; int num; int num2; int shift; if (shortBlocks != 0) { num = shortBlocks; num2 = mode.shortMdctSize; shift = mode.maxLM; } else { num = 1; num2 = mode.shortMdctSize << LM; shift = mode.maxLM - LM; } int num3 = 0; do { for (int i = 0; i < num; i++) { MDCT.clt_mdct_forward(mode.mdct, input[num3], i * num2, output[num3], i, mode.window, overlap, shift, num); } } while (++num3 < CC); if (CC == 2 && C == 1) { for (int j = 0; j < num * num2; j++) { output[0][j] = Inlines.ADD32(Inlines.HALF32(output[0][j]), Inlines.HALF32(output[1][j])); } } if (upsample == 1) { return; } num3 = 0; do { int num4 = num * num2 / upsample; for (int j = 0; j < num4; j++) { output[num3][j] *= upsample; } Arrays.MemSetWithOffset(output[num3], 0, num4, num * num2 - num4); } while (++num3 < C); } internal static void celt_preemphasis(Span pcmp, int pcmp_ptr, Span inp, int inp_ptr, int N, int CC, int upsample, int[] coef, ref int mem, int clip) { int a = coef[0]; int num = mem; if (coef[1] == 0 && upsample == 1 && clip == 0) { for (int i = 0; i < N; i++) { int num2 = pcmp[pcmp_ptr + CC * i]; inp[inp_ptr + i] = Inlines.SHL32(num2, 12) - num; num = Inlines.SHR32(Inlines.MULT16_16(a, num2), 3); } mem = num; return; } int num3 = N / upsample; if (upsample != 1) { Arrays.MemSetWithOffset(inp, 0, inp_ptr, N); } for (int i = 0; i < num3; i++) { inp[inp_ptr + i * upsample] = pcmp[pcmp_ptr + CC * i]; } for (int i = 0; i < N; i++) { int num4 = inp[inp_ptr + i]; inp[inp_ptr + i] = Inlines.SHL32(num4, 12) - num; num = Inlines.SHR32(Inlines.MULT16_16(a, num4), 3); } mem = num; } internal static void celt_preemphasis(short[] pcmp, Span inp, int inp_ptr, int N, int CC, int upsample, int[] coef, BoxedValueInt mem, int clip) { int a = coef[0]; int num = mem.Val; if (coef[1] == 0 && upsample == 1 && clip == 0) { for (int i = 0; i < N; i++) { int num2 = pcmp[CC * i]; inp[inp_ptr + i] = Inlines.SHL32(num2, 12) - num; num = Inlines.SHR32(Inlines.MULT16_16(a, num2), 3); } mem.Val = num; return; } int num3 = N / upsample; if (upsample != 1) { Arrays.MemSetWithOffset(inp, 0, inp_ptr, N); } for (int i = 0; i < num3; i++) { inp[inp_ptr + i * upsample] = pcmp[CC * i]; } for (int i = 0; i < N; i++) { int num4 = inp[inp_ptr + i]; inp[inp_ptr + i] = Inlines.SHL32(num4, 12) - num; num = Inlines.SHR32(Inlines.MULT16_16(a, num4), 3); } mem.Val = num; } internal static int l1_metric(int[] tmp, int N, int LM, int bias) { int num = 0; for (int i = 0; i < N; i++) { num += Inlines.EXTEND32(Inlines.ABS32(tmp[i])); } return Inlines.MAC16_32_Q15(num, LM * bias, num); } internal static int tf_analysis(CeltMode m, int len, int isTransient, int[] tf_res, int lambda, int[][] X, int N0, int LM, out int tf_sum, int tf_estimate, int tf_chan) { int[] array = new int[2]; int num = 0; int bias = Inlines.MULT16_16_Q14(1311, Inlines.MAX16(-4096, 8192 - tf_estimate)); int[] array2 = new int[len]; int[] array3 = new int[m.eBands[len] - m.eBands[len - 1] << LM]; int[] array4 = new int[m.eBands[len] - m.eBands[len - 1] << LM]; int[] array5 = new int[len]; int[] array6 = new int[len]; tf_sum = 0; for (int i = 0; i < len; i++) { int num2 = 0; int num3 = m.eBands[i + 1] - m.eBands[i] << LM; int num4 = ((m.eBands[i + 1] - m.eBands[i] == 1) ? 1 : 0); Arrays.MemCopy(X[tf_chan], m.eBands[i] << LM, array3, 0, num3); int num5 = l1_metric(array3, num3, (isTransient != 0) ? LM : 0, bias); int num6 = num5; if (isTransient != 0 && num4 == 0) { Arrays.MemCopy(array3, 0, array4, 0, num3); Bands.haar1ZeroOffset(array4, num3 >> LM, 1 << LM); num5 = l1_metric(array4, num3, LM + 1, bias); if (num5 < num6) { num6 = num5; num2 = -1; } } for (int j = 0; j < LM + ((isTransient == 0 && num4 == 0) ? 1 : 0); j++) { int lM = ((isTransient == 0) ? (j + 1) : (LM - j - 1)); Bands.haar1ZeroOffset(array3, num3 >> j, 1 << j); num5 = l1_metric(array3, num3, lM, bias); if (num5 < num6) { num6 = num5; num2 = j + 1; } } if (isTransient != 0) { array2[i] = 2 * num2; } else { array2[i] = -2 * num2; } tf_sum += ((isTransient != 0) ? LM : 0) - array2[i] / 2; if (num4 != 0 && (array2[i] == 0 || array2[i] == -2 * LM)) { array2[i]--; } } num = 0; int num7; int num8; for (int k = 0; k < 2; k++) { num7 = 0; num8 = ((isTransient == 0) ? lambda : 0); for (int i = 1; i < len; i++) { int num9 = Inlines.IMIN(num7, num8 + lambda); int num10 = Inlines.IMIN(num7 + lambda, num8); num7 = num9 + Inlines.abs(array2[i] - 2 * Tables.tf_select_table[LM][4 * isTransient + 2 * k]); num8 = num10 + Inlines.abs(array2[i] - 2 * Tables.tf_select_table[LM][4 * isTransient + 2 * k + 1]); } num7 = Inlines.IMIN(num7, num8); array[k] = num7; } if (array[1] < array[0] && isTransient != 0) { num = 1; } num7 = 0; num8 = ((isTransient == 0) ? lambda : 0); for (int i = 1; i < len; i++) { int num11 = num7; int num12 = num8 + lambda; int num13; if (num11 < num12) { num13 = num11; array5[i] = 0; } else { num13 = num12; array5[i] = 1; } num11 = num7 + lambda; num12 = num8; int num14; if (num11 < num12) { num14 = num11; array6[i] = 0; } else { num14 = num12; array6[i] = 1; } num7 = num13 + Inlines.abs(array2[i] - 2 * Tables.tf_select_table[LM][4 * isTransient + 2 * num]); num8 = num14 + Inlines.abs(array2[i] - 2 * Tables.tf_select_table[LM][4 * isTransient + 2 * num + 1]); } tf_res[len - 1] = ((num7 >= num8) ? 1 : 0); for (int i = len - 2; i >= 0; i--) { if (tf_res[i + 1] == 1) { tf_res[i] = array6[i + 1]; } else { tf_res[i] = array5[i + 1]; } } return num; } internal static void tf_encode(int start, int end, int isTransient, int[] tf_res, int LM, int tf_select, EntropyCoder enc, Span encodedData) { uint num = enc.storage * 8; uint num2 = (uint)enc.tell(); int num3 = ((isTransient != 0) ? 2 : 4); int num4 = ((LM > 0 && num2 + num3 + 1 <= num) ? 1 : 0); num -= (uint)num4; int num6; int num5 = (num6 = 0); for (int i = start; i < end; i++) { if (num2 + num3 <= num) { enc.enc_bit_logp(encodedData, tf_res[i] ^ num5, (uint)num3); num2 = (uint)enc.tell(); num5 = tf_res[i]; num6 |= num5; } else { tf_res[i] = num5; } num3 = ((isTransient != 0) ? 4 : 5); } if (num4 != 0 && Tables.tf_select_table[LM][4 * isTransient + num6] != Tables.tf_select_table[LM][4 * isTransient + 2 + num6]) { enc.enc_bit_logp(encodedData, tf_select, 1u); } else { tf_select = 0; } for (int i = start; i < end; i++) { tf_res[i] = Tables.tf_select_table[LM][4 * isTransient + 2 * tf_select + tf_res[i]]; } } internal static int alloc_trim_analysis(CeltMode m, int[][] X, int[][] bandLogE, int end, int LM, int C, AnalysisInfo analysis, ref int stereo_saving, int tf_estimate, int intensity, int surround_trim) { int num = 0; int num2 = 1280; if (C == 2) { int num3 = 0; Span span; for (int i = 0; i < 8; i++) { span = MemoryExtensions.AsSpan(X[0]); Span x = span.Slice(m.eBands[i] << LM); span = MemoryExtensions.AsSpan(X[1]); int a = Kernels.celt_inner_prod(x, span.Slice(m.eBands[i] << LM), m.eBands[i + 1] - m.eBands[i] << LM); num3 = Inlines.ADD16(num3, Inlines.EXTRACT16(Inlines.SHR32(a, 18))); } num3 = Inlines.MULT16_16_Q15(4096, num3); num3 = Inlines.MIN16(1024, Inlines.ABS32(num3)); int num4 = num3; for (int i = 8; i < intensity; i++) { span = MemoryExtensions.AsSpan(X[0]); Span x2 = span.Slice(m.eBands[i] << LM); span = MemoryExtensions.AsSpan(X[1]); int a2 = Kernels.celt_inner_prod(x2, span.Slice(m.eBands[i] << LM), m.eBands[i + 1] - m.eBands[i] << LM); num4 = Inlines.MIN16(num4, Inlines.ABS16(Inlines.EXTRACT16(Inlines.SHR32(a2, 18)))); } num4 = Inlines.MIN16(1024, Inlines.ABS32(num4)); int num5 = Inlines.celt_log2(1049625 - Inlines.MULT16_16(num3, num3)); int num6 = Inlines.MAX16(Inlines.HALF16(num5), Inlines.celt_log2(1049625 - Inlines.MULT16_16(num4, num4))); num5 = Inlines.PSHR32(num5 - 6144, 2); num6 = Inlines.PSHR32(num6 - 6144, 2); num2 += Inlines.MAX16(-1024, Inlines.MULT16_16_Q15(24576, num5)); stereo_saving = Inlines.MIN16(stereo_saving + 64, -Inlines.HALF16(num6)); } int num7 = 0; do { for (int i = 0; i < end - 1; i++) { num += bandLogE[num7][i] * (2 + 2 * i - end); } } while (++num7 < C); num /= C * (end - 1); num2 -= Inlines.MAX16(Inlines.NEG16((short)512), Inlines.MIN16(512, Inlines.SHR16(num + 1024, 2) / 6)); num2 -= Inlines.SHR16(surround_trim, 2); num2 -= 2 * Inlines.SHR16(tf_estimate, 6); if (analysis.valid != 0) { num2 -= Inlines.MAX16(-512, Inlines.MIN16(512, (int)(512f * (analysis.tonality_slope + 0.05f)))); } int b = Inlines.PSHR32(num2, 8); return Inlines.IMAX(0, Inlines.IMIN(10, b)); } internal static int stereo_analysis(CeltMode m, int[][] X, int LM) { int num = 1; int num2 = 1; for (int i = 0; i < 13; i++) { for (int j = m.eBands[i] << LM; j < m.eBands[i + 1] << LM; j++) { int num3 = Inlines.EXTEND32(X[0][j]); int num4 = Inlines.EXTEND32(X[1][j]); int x = Inlines.ADD32(num3, num4); int x2 = Inlines.SUB32(num3, num4); num = Inlines.ADD32(num, Inlines.ADD32(Inlines.ABS32(num3), Inlines.ABS32(num4))); num2 = Inlines.ADD32(num2, Inlines.ADD32(Inlines.ABS32(x), Inlines.ABS32(x2))); } } num2 = Inlines.MULT16_32_Q15((short)23170, num2); int num5 = 13; if (LM <= 1) { num5 -= 8; } return (Inlines.MULT16_32_Q15((m.eBands[13] << LM + 1) + num5, num2) > Inlines.MULT16_32_Q15(m.eBands[13] << LM + 1, num)) ? 1 : 0; } internal static int median_of_5(Span x, int x_ptr) { int num = x[x_ptr + 2]; int num3; int num2; if (x[x_ptr] > x[x_ptr + 1]) { num2 = x[x_ptr + 1]; num3 = x[x_ptr]; } else { num2 = x[x_ptr]; num3 = x[x_ptr + 1]; } int num4; int num5; if (x[x_ptr + 3] > x[x_ptr + 4]) { num4 = x[x_ptr + 4]; num5 = x[x_ptr + 3]; } else { num4 = x[x_ptr + 3]; num5 = x[x_ptr + 4]; } if (num2 > num4) { int num6 = num4; num4 = num2; num2 = num6; int num7 = num5; num5 = num3; num3 = num7; } if (num > num3) { if (num3 < num4) { return Inlines.MIN16(num, num4); } return Inlines.MIN16(num5, num3); } if (num < num4) { return Inlines.MIN16(num3, num4); } return Inlines.MIN16(num, num5); } internal static int median_of_3(Span x, int x_ptr) { int num; int num2; if (x[x_ptr] > x[x_ptr + 1]) { num = x[x_ptr + 1]; num2 = x[x_ptr]; } else { num = x[x_ptr]; num2 = x[x_ptr + 1]; } int num3 = x[x_ptr + 2]; if (num2 < num3) { return num2; } if (num < num3) { return num3; } return num; } internal static int dynalloc_analysis(int[][] bandLogE, int[][] bandLogE2, int nbEBands, int start, int end, int C, int[] offsets, int lsb_depth, short[] logN, int isTransient, int vbr, int constrained_vbr, short[] eBands, int LM, int effectiveBytes, out int tot_boost_, int lfe, int[] surround_dynalloc) { int num = 0; int[][] array = Arrays.InitTwoDimensionalArray(2, nbEBands); int[] array2 = new int[C * nbEBands]; Arrays.MemSetInt(offsets, 0, nbEBands); int num2 = -32666; for (int i = 0; i < end; i++) { array2[i] = Inlines.MULT16_16((short)64, logN[i]) + 512 + Inlines.SHL16(9 - lsb_depth, 10) - Inlines.SHL16(Tables.eMeans[i], 6) + Inlines.MULT16_16(6, (i + 5) * (i + 5)); } int num3 = 0; do { for (int i = 0; i < end; i++) { num2 = Inlines.MAX16(num2, bandLogE[num3][i] - array2[i]); } } while (++num3 < C); if (effectiveBytes > 50 && LM >= 1 && lfe == 0) { int num4 = 0; num3 = 0; do { int[] array3 = array[num3]; array3[0] = bandLogE2[num3][0]; for (int i = 1; i < end; i++) { if (bandLogE2[num3][i] > bandLogE2[num3][i - 1] + 512) { num4 = i; } array3[i] = Inlines.MIN16(array3[i - 1] + 1536, bandLogE2[num3][i]); } for (int i = num4 - 1; i >= 0; i--) { array3[i] = Inlines.MIN16(array3[i], Inlines.MIN16(array3[i + 1] + 2048, bandLogE2[num3][i])); } int num5 = 1024; for (int i = 2; i < end - 2; i++) { array3[i] = Inlines.MAX16(array3[i], median_of_5(bandLogE2[num3], i - 2) - num5); } int b = median_of_3(bandLogE2[num3], 0) - num5; array3[0] = Inlines.MAX16(array3[0], b); array3[1] = Inlines.MAX16(array3[1], b); b = median_of_3(bandLogE2[num3], end - 3) - num5; array3[end - 2] = Inlines.MAX16(array3[end - 2], b); array3[end - 1] = Inlines.MAX16(array3[end - 1], b); for (int i = 0; i < end; i++) { array3[i] = Inlines.MAX16(array3[i], array2[i]); } } while (++num3 < C); if (C == 2) { for (int i = start; i < end; i++) { array[1][i] = Inlines.MAX16(array[1][i], array[0][i] - 4096); array[0][i] = Inlines.MAX16(array[0][i], array[1][i] - 4096); array[0][i] = Inlines.HALF16(Inlines.MAX16(0, bandLogE[0][i] - array[0][i]) + Inlines.MAX16(0, bandLogE[1][i] - array[1][i])); } } else { for (int i = start; i < end; i++) { array[0][i] = Inlines.MAX16(0, bandLogE[0][i] - array[0][i]); } } for (int i = start; i < end; i++) { array[0][i] = Inlines.MAX16(array[0][i], surround_dynalloc[i]); } if ((vbr == 0 || constrained_vbr != 0) && isTransient == 0) { for (int i = start; i < end; i++) { array[0][i] = Inlines.HALF16(array[0][i]); } } for (int i = start; i < end; i++) { if (i < 8) { array[0][i] *= 2; } if (i >= 12) { array[0][i] = Inlines.HALF16(array[0][i]); } array[0][i] = Inlines.MIN16(array[0][i], 4096); int num6 = C * (eBands[i + 1] - eBands[i]) << LM; int num7; int num8; if (num6 < 6) { num7 = Inlines.SHR32(array[0][i], 10); num8 = num7 * num6 << 3; } else if (num6 > 48) { num7 = Inlines.SHR32(array[0][i] * 8, 10); num8 = (num7 * num6 << 3) / 8; } else { num7 = Inlines.SHR32(array[0][i] * num6 / 6, 10); num8 = num7 * 6 << 3; } if ((vbr == 0 || (constrained_vbr != 0 && isTransient == 0)) && num + num8 >> 3 >> 3 > effectiveBytes / 4) { int num9 = effectiveBytes / 4 << 3 << 3; offsets[i] = num9 - num; num = num9; break; } offsets[i] = num7; num += num8; } } tot_boost_ = num; return num2; } internal static void deemphasis(int[][] input, int[] input_ptrs, Span pcm, int pcm_ptr, int N, int C, int downsample, int[] coef, int[] mem, int accum) { int num = 0; if (downsample == 1 && C == 2 && accum == 0) { deemphasis_stereo_simple(input, input_ptrs, pcm, pcm_ptr, N, coef[0], mem); return; } int[] array = new int[N]; int a = coef[0]; int num2 = N / downsample; int num3 = 0; do { int num4 = mem[num3]; int[] array2 = input[num3]; int num5 = input_ptrs[num3]; int num6 = pcm_ptr + num3; if (downsample > 1) { for (int i = 0; i < N; i++) { int num7 = array2[num5 + i] + num4; num4 = Inlines.MULT16_32_Q15(a, num7); array[i] = num7; } num = 1; } else if (accum != 0) { for (int i = 0; i < N; i++) { int num8 = array2[num5 + i] + num4; num4 = Inlines.MULT16_32_Q15(a, num8); pcm[num6 + i * C] = Inlines.SAT16(Inlines.ADD32(pcm[num6 + i * C], Inlines.SIG2WORD16(num8))); } } else { for (int i = 0; i < N; i++) { int num9 = array2[num5 + i] + num4; if (array2[num5 + i] > 0 && num4 > 0 && num9 < 0) { num9 = int.MaxValue; num4 = int.MaxValue; } else { num4 = Inlines.MULT16_32_Q15(a, num9); } pcm[num6 + i * C] = Inlines.SIG2WORD16(num9); } } mem[num3] = num4; if (num != 0) { for (int i = 0; i < num2; i++) { pcm[num6 + i * C] = Inlines.SIG2WORD16(array[i * downsample]); } } } while (++num3 < C); } internal static void deemphasis_stereo_simple(int[][] input, int[] input_ptrs, Span pcm, int pcm_ptr, int N, int coef0, int[] mem) { int[] array = input[0]; int[] array2 = input[1]; int num = input_ptrs[0]; int num2 = input_ptrs[1]; int num3 = mem[0]; int num4 = mem[1]; for (int i = 0; i < N; i++) { int num5 = array[num + i] + num3; int num6 = array2[num2 + i] + num4; num3 = Inlines.MULT16_32_Q15(coef0, num5); num4 = Inlines.MULT16_32_Q15(coef0, num6); pcm[pcm_ptr + 2 * i] = Inlines.SIG2WORD16(num5); pcm[pcm_ptr + 2 * i + 1] = Inlines.SIG2WORD16(num6); } mem[0] = num3; mem[1] = num4; } internal static void celt_synthesis(CeltMode mode, int[][] X, int[][] out_syn, int[] out_syn_ptrs, int[] oldBandE, int start, int effEnd, int C, int CC, int isTransient, int LM, int downsample, int silence) { int overlap = mode.overlap; int nbEBands = mode.nbEBands; int num = mode.shortMdctSize << LM; int[] array = new int[num]; int num2 = 1 << LM; int num3; int num4; int shift; if (isTransient != 0) { num3 = num2; num4 = mode.shortMdctSize; shift = mode.maxLM; } else { num3 = 1; num4 = mode.shortMdctSize << LM; shift = mode.maxLM - LM; } if (CC == 2 && C == 1) { Bands.denormalise_bands(mode, X[0], array, 0, oldBandE, 0, start, effEnd, num2, downsample, silence); int num5 = out_syn_ptrs[1] + overlap / 2; Arrays.MemCopy(array, 0, out_syn[1], num5, num); for (int i = 0; i < num3; i++) { MDCT.clt_mdct_backward(mode.mdct, out_syn[1], num5 + i, out_syn[0], out_syn_ptrs[0] + num4 * i, mode.window, overlap, shift, num3); } for (int i = 0; i < num3; i++) { MDCT.clt_mdct_backward(mode.mdct, array, i, out_syn[1], out_syn_ptrs[1] + num4 * i, mode.window, overlap, shift, num3); } return; } if (CC == 1 && C == 2) { int num6 = out_syn_ptrs[0] + overlap / 2; Bands.denormalise_bands(mode, X[0], array, 0, oldBandE, 0, start, effEnd, num2, downsample, silence); Bands.denormalise_bands(mode, X[1], out_syn[0], num6, oldBandE, nbEBands, start, effEnd, num2, downsample, silence); for (int j = 0; j < num; j++) { array[j] = Inlines.HALF32(Inlines.ADD32(array[j], out_syn[0][num6 + j])); } for (int i = 0; i < num3; i++) { MDCT.clt_mdct_backward(mode.mdct, array, i, out_syn[0], out_syn_ptrs[0] + num4 * i, mode.window, overlap, shift, num3); } return; } int num7 = 0; do { Bands.denormalise_bands(mode, X[num7], array, 0, oldBandE, num7 * nbEBands, start, effEnd, num2, downsample, silence); for (int i = 0; i < num3; i++) { MDCT.clt_mdct_backward(mode.mdct, array, i, out_syn[num7], out_syn_ptrs[num7] + num4 * i, mode.window, overlap, shift, num3); } } while (++num7 < CC); } internal static void tf_decode(int start, int end, int isTransient, int[] tf_res, int LM, EntropyCoder dec, ReadOnlySpan encodedData) { uint num = dec.storage * 8; uint num2 = (uint)dec.tell(); int num3 = ((isTransient != 0) ? 2 : 4); int num4 = ((LM > 0 && num2 + num3 + 1 <= num) ? 1 : 0); num -= (uint)num4; int num6; int num5 = (num6 = 0); for (int i = start; i < end; i++) { if (num2 + num3 <= num) { num6 ^= dec.dec_bit_logp(encodedData, (uint)num3); num2 = (uint)dec.tell(); num5 |= num6; } tf_res[i] = num6; num3 = ((isTransient != 0) ? 4 : 5); } int num7 = 0; if (num4 != 0 && Tables.tf_select_table[LM][4 * isTransient + num5] != Tables.tf_select_table[LM][4 * isTransient + 2 + num5]) { num7 = dec.dec_bit_logp(encodedData, 1u); } for (int i = start; i < end; i++) { tf_res[i] = Tables.tf_select_table[LM][4 * isTransient + 2 * num7 + tf_res[i]]; } } internal static int celt_plc_pitch_search(int[][] decode_mem, int C) { int[] array = new int[1024]; Pitch.pitch_downsample(decode_mem, array, 2048, C); Pitch.pitch_search(array, 360, array, 1328, 620, out var pitch); return 720 - pitch; } internal static int resampling_factor(int rate) { return rate switch { 48000 => 1, 24000 => 2, 16000 => 3, 12000 => 4, 8000 => 6, _ => 0, }; } internal static void comb_filter_const(Span y, int y_ptr, Span x, int x_ptr, int T, int N, int g10, int g11, int g12) { int num = x_ptr - T; int b = x[num - 2]; int num2 = x[num - 1]; int num3 = x[num]; int num4 = x[num + 1]; for (int i = 0; i < N; i++) { int num5 = x[num + i + 2]; y[y_ptr + i] = x[x_ptr + i] + Inlines.MULT16_32_Q15(g10, num3) + Inlines.MULT16_32_Q15(g11, Inlines.ADD32(num4, num2)) + Inlines.MULT16_32_Q15(g12, Inlines.ADD32(num5, b)); b = num2; num2 = num3; num3 = num4; num4 = num5; } } internal static void comb_filter(Span y, int y_ptr, Span x, int x_ptr, int T0, int T1, int N, int g0, int g1, int tapset0, int tapset1, int[] window, int overlap) { if (g0 != 0 || g1 != 0) { int b = Inlines.MULT16_16_P15(g0, gains[tapset0][0]); int b2 = Inlines.MULT16_16_P15(g0, gains[tapset0][1]); int b3 = Inlines.MULT16_16_P15(g0, gains[tapset0][2]); int num = Inlines.MULT16_16_P15(g1, gains[tapset1][0]); int num2 = Inlines.MULT16_16_P15(g1, gains[tapset1][1]); int num3 = Inlines.MULT16_16_P15(g1, gains[tapset1][2]); int num4 = x[x_ptr - T1 + 1]; int num5 = x[x_ptr - T1]; int num6 = x[x_ptr - T1 - 1]; int b4 = x[x_ptr - T1 - 2]; if (g0 == g1 && T0 == T1 && tapset0 == tapset1) { overlap = 0; } int i; for (i = 0; i < overlap; i++) { int num7 = x[x_ptr + i - T1 + 2]; int num8 = Inlines.MULT16_16_Q15(window[i], window[i]); y[y_ptr + i] = x[x_ptr + i] + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((short)(32767 - num8), b), x[x_ptr + i - T0]) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((short)(32767 - num8), b2), Inlines.ADD32(x[x_ptr + i - T0 + 1], x[x_ptr + i - T0 - 1])) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15((short)(32767 - num8), b3), Inlines.ADD32(x[x_ptr + i - T0 + 2], x[x_ptr + i - T0 - 2])) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(num8, num), num5) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(num8, num2), Inlines.ADD32(num4, num6)) + Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(num8, num3), Inlines.ADD32(num7, b4)); b4 = num6; num6 = num5; num5 = num4; num4 = num7; } if (g1 != 0) { comb_filter_const(y, y_ptr + i, x, x_ptr + i, T1, N - i, num, num2, num3); } } } internal static void init_caps(CeltMode m, int[] cap, int LM, int C) { for (int i = 0; i < m.nbEBands; i++) { int num = m.eBands[i + 1] - m.eBands[i] << LM; cap[i] = (m.cache.caps[m.nbEBands * (2 * LM + C - 1) + i] + 64) * C * num >> 2; } } } internal static class CeltConstants { internal const int Q15ONE = 32767; internal const float CELT_SIG_SCALE = 32768f; internal const int SIG_SHIFT = 12; internal const int NORM_SCALING = 16384; internal const int DB_SHIFT = 10; internal const int EPSILON = 1; internal const int VERY_SMALL = 0; internal const short VERY_LARGE16 = short.MaxValue; internal const short Q15_ONE = short.MaxValue; internal const int COMBFILTER_MAXPERIOD = 1024; internal const int COMBFILTER_MINPERIOD = 15; internal const int DECODE_BUFFER_SIZE = 2048; internal const int BITALLOC_SIZE = 11; internal const int MAX_PERIOD = 1024; internal const int TOTAL_MODES = 1; internal const int MAX_PSEUDO = 40; internal const int LOG_MAX_PSEUDO = 6; internal const int CELT_MAX_PULSES = 128; internal const int MAX_FINE_BITS = 8; internal const int FINE_OFFSET = 21; internal const int QTHETA_OFFSET = 4; internal const int QTHETA_OFFSET_TWOPHASE = 16; internal const int PLC_PITCH_LAG_MAX = 720; internal const int PLC_PITCH_LAG_MIN = 100; internal const int LPC_ORDER = 24; } internal static class CeltLPC { private const int LPC_ORDER = 24; internal static void celt_lpc(int[] _lpc, int[] ac, int p) { int num = ac[0]; Span span = stackalloc int[24]; if (ac[0] != 0) { for (int i = 0; i < p; i++) { int num2 = 0; for (int j = 0; j < i; j++) { num2 += Inlines.MULT32_32_Q31(span[j], ac[i - j]); } num2 += Inlines.SHR32(ac[i + 1], 3); int num3 = -Inlines.frac_div32(Inlines.SHL32(num2, 3), num); span[i] = Inlines.SHR32(num3, 3); for (int j = 0; j < i + 1 >> 1; j++) { int num4 = span[j]; int num5 = span[i - 1 - j]; span[j] = num4 + Inlines.MULT32_32_Q31(num3, num5); span[i - 1 - j] = num5 + Inlines.MULT32_32_Q31(num3, num4); } num -= Inlines.MULT32_32_Q31(Inlines.MULT32_32_Q31(num3, num3), num); if (num < Inlines.SHR32(ac[0], 10)) { break; } } } for (int i = 0; i < p; i++) { _lpc[i] = Inlines.ROUND16(span[i], 16); } } internal static void celt_iir(Span _x, int[] den, Span _y, int N, int ord, Span mem) { int[] array = new int[ord]; int[] array2 = new int[N + ord]; int i; for (i = 0; i < ord; i++) { array[i] = den[ord - i - 1]; } for (i = 0; i < ord; i++) { array2[i] = -mem[ord - i - 1]; } for (; i < N + ord; i++) { array2[i] = 0; } for (i = 0; i < N - 3; i += 4) { int sum = _x[i]; int sum2 = _x[i + 1]; int sum3 = _x[i + 2]; int sum4 = _x[i + 3]; Kernels.xcorr_kernel(array, 0, array2, i, ref sum, ref sum2, ref sum3, ref sum4, ord); array2[i + ord] = -Inlines.ROUND16(sum, 12); _y[i] = sum; sum2 = Inlines.MAC16_16(sum2, array2[i + ord], den[0]); array2[i + ord + 1] = -Inlines.ROUND16(sum2, 12); _y[i + 1] = sum2; sum3 = Inlines.MAC16_16(sum3, array2[i + ord + 1], den[0]); sum3 = Inlines.MAC16_16(sum3, array2[i + ord], den[1]); array2[i + ord + 2] = -Inlines.ROUND16(sum3, 12); _y[i + 2] = sum3; sum4 = Inlines.MAC16_16(sum4, array2[i + ord + 2], den[0]); sum4 = Inlines.MAC16_16(sum4, array2[i + ord + 1], den[1]); sum4 = Inlines.MAC16_16(sum4, array2[i + ord], den[2]); array2[i + ord + 3] = -Inlines.ROUND16(sum4, 12); _y[i + 3] = sum4; } for (; i < N; i++) { int num = _x[i]; for (int j = 0; j < ord; j++) { num -= Inlines.MULT16_16(array[j], array2[i + j]); } array2[i + ord] = Inlines.ROUND16(num, 12); _y[i] = num; } for (i = 0; i < ord; i++) { mem[i] = _y[N - i - 1]; } } } internal static class CeltPitchXCorr { internal static int pitch_xcorr(int[] _x, int x_idx, int[] _y, int y_idx, Span xcorr, int len, int max_pitch) { int num = 1; int i; if (Vector.IsHardwareAccelerated) { for (i = 0; i < max_pitch - 3; i += 4) { int sum = 0; int sum2 = 0; int sum3 = 0; int sum4 = 0; Kernels.xcorr_kernel_vector(_x, x_idx, _y, y_idx + i, ref sum, ref sum2, ref sum3, ref sum4, len); xcorr[i] = sum; xcorr[i + 1] = sum2; xcorr[i + 2] = sum3; xcorr[i + 3] = sum4; sum = Inlines.MAX32(sum, sum2); sum3 = Inlines.MAX32(sum3, sum4); sum = Inlines.MAX32(sum, sum3); num = Inlines.MAX32(num, sum); } } else { for (i = 0; i < max_pitch - 3; i += 4) { int sum5 = 0; int sum6 = 0; int sum7 = 0; int sum8 = 0; Kernels.xcorr_kernel(_x, x_idx, _y, y_idx + i, ref sum5, ref sum6, ref sum7, ref sum8, len); xcorr[i] = sum5; xcorr[i + 1] = sum6; xcorr[i + 2] = sum7; xcorr[i + 3] = sum8; sum5 = Inlines.MAX32(sum5, sum6); sum7 = Inlines.MAX32(sum7, sum8); sum5 = Inlines.MAX32(sum5, sum7); num = Inlines.MAX32(num, sum5); } } for (; i < max_pitch; i++) { int num2 = Kernels.celt_inner_prod(MemoryExtensions.AsSpan(_x), MemoryExtensions.AsSpan(_y, i), len); xcorr[i] = num2; num = Inlines.MAX32(num, num2); } return num; } internal static int pitch_xcorr(short[] _x, int x_idx, short[] _y, int y_idx, int[] xcorr, int len, int max_pitch) { int num = 1; int i; for (i = 0; i < max_pitch - 3; i += 4) { int sum = 0; int sum2 = 0; int sum3 = 0; int sum4 = 0; Kernels.xcorr_kernel(_x, x_idx, _y, y_idx + i, ref sum, ref sum2, ref sum3, ref sum4, len); xcorr[i] = sum; xcorr[i + 1] = sum2; xcorr[i + 2] = sum3; xcorr[i + 3] = sum4; sum = Inlines.MAX32(sum, sum2); sum3 = Inlines.MAX32(sum3, sum4); sum = Inlines.MAX32(sum, sum3); num = Inlines.MAX32(num, sum); } for (; i < max_pitch; i++) { num = Inlines.MAX32(num, xcorr[i] = Kernels.celt_inner_prod(MemoryExtensions.AsSpan(_x, x_idx), MemoryExtensions.AsSpan(_y, y_idx + i), len)); } return num; } } internal static class CWRS { internal static readonly uint[] CELT_PVQ_U_ROW = new uint[15] { 0u, 176u, 351u, 525u, 698u, 870u, 1041u, 1131u, 1178u, 1207u, 1226u, 1240u, 1248u, 1254u, 1257u }; private static uint CELT_PVQ_U(int _n, int _k) { return Tables.CELT_PVQ_U_DATA[CELT_PVQ_U_ROW[Inlines.IMIN(_n, _k)] + Inlines.IMAX(_n, _k)]; } private static uint CELT_PVQ_V(int _n, int _k) { return CELT_PVQ_U(_n, _k) + CELT_PVQ_U(_n, _k + 1); } internal static uint icwrs(int _n, int[] _y) { int num = _n - 1; uint num2 = ((_y[num] < 0) ? 1u : 0u); int num3 = Inlines.abs(_y[num]); do { num--; num2 += CELT_PVQ_U(_n - num, num3); num3 += Inlines.abs(_y[num]); if (_y[num] < 0) { num2 += CELT_PVQ_U(_n - num, num3 + 1); } } while (num > 0); return num2; } internal static void encode_pulses(int[] _y, int _n, int _k, EntropyCoder _enc, Span encodedData) { _enc.enc_uint(encodedData, icwrs(_n, _y), CELT_PVQ_V(_n, _k)); } internal static int cwrsi(int _n, int _k, uint _i, int[] _y) { int c = 0; int num = 0; uint num3; int num5; int num4; short num7; while (_n > 2) { if (_k >= _n) { uint num2 = CELT_PVQ_U_ROW[_n]; num3 = Tables.CELT_PVQ_U_DATA[num2 + _k + 1]; num4 = 0 - ((_i >= num3) ? 1 : 0); _i -= num3 & (uint)num4; num5 = _k; uint num6 = Tables.CELT_PVQ_U_DATA[num2 + _n]; if (num6 > _i) { _k = _n; do { num3 = Tables.CELT_PVQ_U_DATA[CELT_PVQ_U_ROW[--_k] + _n]; } while (num3 > _i); } else { for (num3 = Tables.CELT_PVQ_U_DATA[num2 + _k]; num3 > _i; num3 = Tables.CELT_PVQ_U_DATA[num2 + _k]) { _k--; } } _i -= num3; num7 = (short)((num5 - _k + num4) ^ num4); _y[num++] = num7; c = Inlines.MAC16_16(c, num7, num7); } else { num3 = Tables.CELT_PVQ_U_DATA[CELT_PVQ_U_ROW[_k] + _n]; uint num6 = Tables.CELT_PVQ_U_DATA[CELT_PVQ_U_ROW[_k + 1] + _n]; if (num3 <= _i && _i < num6) { _i -= num3; _y[num++] = 0; } else { num4 = 0 - ((_i >= num6) ? 1 : 0); _i -= num6 & (uint)num4; num5 = _k; do { num3 = Tables.CELT_PVQ_U_DATA[CELT_PVQ_U_ROW[--_k] + _n]; } while (num3 > _i); _i -= num3; num7 = (short)((num5 - _k + num4) ^ num4); _y[num++] = num7; c = Inlines.MAC16_16(c, num7, num7); } } _n--; } num3 = (uint)(2 * _k + 1); num4 = 0 - ((_i >= num3) ? 1 : 0); _i -= num3 & (uint)num4; num5 = _k; _k = (int)(_i + 1 >> 1); if (_k != 0) { _i -= (uint)(2 * _k - 1); } num7 = (short)((num5 - _k + num4) ^ num4); _y[num++] = num7; c = Inlines.MAC16_16(c, num7, num7); num4 = (int)(0 - _i); num7 = (short)(_y[num] = (short)((_k + num4) ^ num4)); return Inlines.MAC16_16(c, num7, num7); } internal static int decode_pulses(int[] _y, int _n, int _k, EntropyCoder _dec, ReadOnlySpan encodedData) { return cwrsi(_n, _k, _dec.dec_uint(encodedData, CELT_PVQ_V(_n, _k)), _y); } } internal static class Kernels { internal static void celt_fir(Span x, Span num, Span y, int N, int ord, Span mem) { short[] array = new short[ord]; short[] array2 = new short[N + ord]; int i; for (i = 0; i < ord; i++) { array[i] = num[ord - i - 1]; } for (i = 0; i < ord; i++) { array2[i] = mem[ord - i - 1]; } for (i = 0; i < N; i++) { array2[i + ord] = x[i]; } for (i = 0; i < ord; i++) { mem[i] = x[N - i - 1]; } for (i = 0; i < N - 3; i += 4) { int sum = 0; int sum2 = 0; int sum3 = 0; int sum4 = 0; xcorr_kernel(array, 0, array2, i, ref sum, ref sum2, ref sum3, ref sum4, ord); y[i] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i]), Inlines.PSHR32(sum, 12))); y[i + 1] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 1]), Inlines.PSHR32(sum2, 12))); y[i + 2] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 2]), Inlines.PSHR32(sum3, 12))); y[i + 3] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 3]), Inlines.PSHR32(sum4, 12))); } for (; i < N; i++) { int num2 = 0; for (int j = 0; j < ord; j++) { num2 = Inlines.MAC16_16(num2, array[j], array2[i + j]); } y[i] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i]), Inlines.PSHR32(num2, 12))); } } internal static void celt_fir(Span x, Span num, Span y, int N, int ord, Span mem) { int[] array = new int[ord]; int[] array2 = new int[N + ord]; int i; for (i = 0; i < ord; i++) { array[i] = num[ord - i - 1]; } for (i = 0; i < ord; i++) { array2[i] = mem[ord - i - 1]; } for (i = 0; i < N; i++) { array2[i + ord] = x[i]; } for (i = 0; i < ord; i++) { mem[i] = x[N - i - 1]; } for (i = 0; i < N - 3; i += 4) { int sum = 0; int sum2 = 0; int sum3 = 0; int sum4 = 0; xcorr_kernel(array, 0, array2, i, ref sum, ref sum2, ref sum3, ref sum4, ord); y[i] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i]), Inlines.PSHR32(sum, 12))); y[i + 1] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 1]), Inlines.PSHR32(sum2, 12))); y[i + 2] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 2]), Inlines.PSHR32(sum3, 12))); y[i + 3] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i + 3]), Inlines.PSHR32(sum4, 12))); } for (; i < N; i++) { int num2 = 0; for (int j = 0; j < ord; j++) { num2 = Inlines.MAC16_16(num2, array[j], array2[i + j]); } y[i] = Inlines.SATURATE16(Inlines.ADD32(Inlines.EXTEND32(x[i]), Inlines.PSHR32(num2, 12))); } } internal static void xcorr_kernel(short[] x, int x_idx, short[] y, int y_idx, ref int sum0, ref int sum1, ref int sum2, ref int sum3, int len) { int num = x_idx; int num2 = y_idx; short b = 0; short b2 = y[num2++]; short b3 = y[num2++]; short b4 = y[num2++]; int i; for (i = 0; i < len - 3; i += 4) { short a = x[num++]; b = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b2); sum1 = Inlines.MAC16_16(sum1, a, b3); sum2 = Inlines.MAC16_16(sum2, a, b4); sum3 = Inlines.MAC16_16(sum3, a, b); a = x[num++]; b2 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b3); sum1 = Inlines.MAC16_16(sum1, a, b4); sum2 = Inlines.MAC16_16(sum2, a, b); sum3 = Inlines.MAC16_16(sum3, a, b2); a = x[num++]; b3 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b4); sum1 = Inlines.MAC16_16(sum1, a, b); sum2 = Inlines.MAC16_16(sum2, a, b2); sum3 = Inlines.MAC16_16(sum3, a, b3); a = x[num++]; b4 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b); sum1 = Inlines.MAC16_16(sum1, a, b2); sum2 = Inlines.MAC16_16(sum2, a, b3); sum3 = Inlines.MAC16_16(sum3, a, b4); } if (i++ < len) { short a2 = x[num++]; b = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a2, b2); sum1 = Inlines.MAC16_16(sum1, a2, b3); sum2 = Inlines.MAC16_16(sum2, a2, b4); sum3 = Inlines.MAC16_16(sum3, a2, b); } if (i++ < len) { short a3 = x[num++]; b2 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a3, b3); sum1 = Inlines.MAC16_16(sum1, a3, b4); sum2 = Inlines.MAC16_16(sum2, a3, b); sum3 = Inlines.MAC16_16(sum3, a3, b2); } if (i < len) { short a4 = x[num++]; b3 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a4, b4); sum1 = Inlines.MAC16_16(sum1, a4, b); sum2 = Inlines.MAC16_16(sum2, a4, b2); sum3 = Inlines.MAC16_16(sum3, a4, b3); } } internal static void xcorr_kernel(int[] x, int x_idx, int[] y, int y_idx, ref int sum0, ref int sum1, ref int sum2, ref int sum3, int len) { int num = x_idx; int num2 = y_idx; int b = 0; int b2 = y[num2++]; int b3 = y[num2++]; int b4 = y[num2++]; int i; for (i = 0; i < len - 3; i += 4) { int a = x[num++]; b = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b2); sum1 = Inlines.MAC16_16(sum1, a, b3); sum2 = Inlines.MAC16_16(sum2, a, b4); sum3 = Inlines.MAC16_16(sum3, a, b); a = x[num++]; b2 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b3); sum1 = Inlines.MAC16_16(sum1, a, b4); sum2 = Inlines.MAC16_16(sum2, a, b); sum3 = Inlines.MAC16_16(sum3, a, b2); a = x[num++]; b3 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b4); sum1 = Inlines.MAC16_16(sum1, a, b); sum2 = Inlines.MAC16_16(sum2, a, b2); sum3 = Inlines.MAC16_16(sum3, a, b3); a = x[num++]; b4 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a, b); sum1 = Inlines.MAC16_16(sum1, a, b2); sum2 = Inlines.MAC16_16(sum2, a, b3); sum3 = Inlines.MAC16_16(sum3, a, b4); } if (i++ < len) { int a2 = x[num++]; b = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a2, b2); sum1 = Inlines.MAC16_16(sum1, a2, b3); sum2 = Inlines.MAC16_16(sum2, a2, b4); sum3 = Inlines.MAC16_16(sum3, a2, b); } if (i++ < len) { int a3 = x[num++]; b2 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a3, b3); sum1 = Inlines.MAC16_16(sum1, a3, b4); sum2 = Inlines.MAC16_16(sum2, a3, b); sum3 = Inlines.MAC16_16(sum3, a3, b2); } if (i < len) { int a4 = x[num++]; b3 = y[num2++]; sum0 = Inlines.MAC16_16(sum0, a4, b4); sum1 = Inlines.MAC16_16(sum1, a4, b); sum2 = Inlines.MAC16_16(sum2, a4, b2); sum3 = Inlines.MAC16_16(sum3, a4, b3); } } internal static void xcorr_kernel_vector(int[] x, int x_idx, int[] y, int y_idx, ref int sum0, ref int sum1, ref int sum2, ref int sum3, int len) { int i = 0; for (int num = len - 4 - (len - 4) % Vector.Count; i < num; i += Vector.Count) { Vector left = new Vector(x, x_idx + i); sum0 += Vector.Dot(Vector.One, Vector.Multiply(left, new Vector(y, y_idx + i))); sum1 += Vector.Dot(Vector.One, Vector.Multiply(left, new Vector(y, y_idx + i + 1))); sum2 += Vector.Dot(Vector.One, Vector.Multiply(left, new Vector(y, y_idx + i + 2))); sum3 += Vector.Dot(Vector.One, Vector.Multiply(left, new Vector(y, y_idx + i + 3))); } for (; i < len; i++) { int a = x[x_idx + i]; sum0 = Inlines.MAC16_16(sum0, a, y[y_idx + i]); sum1 = Inlines.MAC16_16(sum1, a, y[y_idx + i + 1]); sum2 = Inlines.MAC16_16(sum2, a, y[y_idx + i + 2]); sum3 = Inlines.MAC16_16(sum3, a, y[y_idx + i + 3]); } } internal static int celt_inner_prod(Span x, Span y, int N) { int num = 0; for (int i = 0; i < N; i++) { num = Inlines.MAC16_16(num, x[i], y[i]); } return num; } internal static int celt_inner_prod(Span x, Span y, int N) { int num = 0; for (int i = 0; i < N; i++) { num = Inlines.MAC16_16(num, x[i], y[i]); } return num; } internal static void dual_inner_prod(Span x, Span y01, Span y02, int N, out int xy1, out int xy2) { int num = 0; int num2 = 0; for (int i = 0; i < N; i++) { num = Inlines.MAC16_16(num, x[i], y01[i]); num2 = Inlines.MAC16_16(num2, x[i], y02[i]); } xy1 = num; xy2 = num2; } } internal static class KissFFT { internal const int MAXFACTORS = 8; internal static int S_MUL(int a, int b) { return Inlines.MULT16_32_Q15(b, a); } internal static int S_MUL(int a, short b) { return Inlines.MULT16_32_Q15(b, a); } internal static int HALF_OF(int x) { return x >> 1; } internal static void kf_bfly2(Span Fout, int fout_ptr, int m, int N) { short b = 23170; for (int i = 0; i < N; i++) { int num = fout_ptr + 8; int num2 = Fout[num]; int num3 = Fout[num + 1]; Fout[num] = Fout[fout_ptr] - num2; Fout[num + 1] = Fout[fout_ptr + 1] - num3; Fout[fout_ptr] += num2; Fout[fout_ptr + 1] += num3; num2 = S_MUL(Fout[num + 2] + Fout[num + 3], b); num3 = S_MUL(Fout[num + 3] - Fout[num + 2], b); Fout[num + 2] = Fout[fout_ptr + 2] - num2; Fout[num + 3] = Fout[fout_ptr + 3] - num3; Fout[fout_ptr + 2] += num2; Fout[fout_ptr + 3] += num3; num2 = Fout[num + 5]; num3 = -Fout[num + 4]; Fout[num + 4] = Fout[fout_ptr + 4] - num2; Fout[num + 5] = Fout[fout_ptr + 5] - num3; Fout[fout_ptr + 4] += num2; Fout[fout_ptr + 5] += num3; num2 = S_MUL(Fout[num + 7] - Fout[num + 6], b); num3 = S_MUL(-Fout[num + 7] - Fout[num + 6], b); Fout[num + 6] = Fout[fout_ptr + 6] - num2; Fout[num + 7] = Fout[fout_ptr + 7] - num3; Fout[fout_ptr + 6] += num2; Fout[fout_ptr + 7] += num3; fout_ptr += 16; } } internal static void kf_bfly4(Span Fout, int fout_ptr, int fstride, FFTState st, int m, int N, int mm) { if (m == 1) { for (int i = 0; i < N; i++) { int num = Fout[fout_ptr] - Fout[fout_ptr + 4]; int num2 = Fout[fout_ptr + 1] - Fout[fout_ptr + 5]; Fout[fout_ptr] += Fout[fout_ptr + 4]; Fout[fout_ptr + 1] += Fout[fout_ptr + 5]; int num3 = Fout[fout_ptr + 2] + Fout[fout_ptr + 6]; int num4 = Fout[fout_ptr + 3] + Fout[fout_ptr + 7]; Fout[fout_ptr + 4] = Fout[fout_ptr] - num3; Fout[fout_ptr + 5] = Fout[fout_ptr + 1] - num4; Fout[fout_ptr] += num3; Fout[fout_ptr + 1] += num4; num3 = Fout[fout_ptr + 2] - Fout[fout_ptr + 6]; num4 = Fout[fout_ptr + 3] - Fout[fout_ptr + 7]; Fout[fout_ptr + 2] = num + num4; Fout[fout_ptr + 3] = num2 - num3; Fout[fout_ptr + 6] = num - num4; Fout[fout_ptr + 7] = num2 + num3; fout_ptr += 8; } return; } int num5 = fout_ptr; for (int i = 0; i < N; i++) { fout_ptr = num5 + 2 * i * mm; int num6 = fout_ptr + 2 * m; int num7 = fout_ptr + 4 * m; int num8 = fout_ptr + 6 * m; int num10; int num11; int num9 = (num10 = (num11 = 0)); for (int j = 0; j < m; j++) { int num12 = S_MUL(Fout[num6], st.twiddles[num11]) - S_MUL(Fout[num6 + 1], st.twiddles[num11 + 1]); int num13 = S_MUL(Fout[num6], st.twiddles[num11 + 1]) + S_MUL(Fout[num6 + 1], st.twiddles[num11]); int num14 = S_MUL(Fout[num7], st.twiddles[num10]) - S_MUL(Fout[num7 + 1], st.twiddles[num10 + 1]); int num15 = S_MUL(Fout[num7], st.twiddles[num10 + 1]) + S_MUL(Fout[num7 + 1], st.twiddles[num10]); int num16 = S_MUL(Fout[num8], st.twiddles[num9]) - S_MUL(Fout[num8 + 1], st.twiddles[num9 + 1]); int num17 = S_MUL(Fout[num8], st.twiddles[num9 + 1]) + S_MUL(Fout[num8 + 1], st.twiddles[num9]); int num18 = Fout[fout_ptr] - num14; int num19 = Fout[fout_ptr + 1] - num15; Fout[fout_ptr] += num14; Fout[fout_ptr + 1] += num15; int num20 = num12 + num16; int num21 = num13 + num17; int num22 = num12 - num16; int num23 = num13 - num17; Fout[num7] = Fout[fout_ptr] - num20; Fout[num7 + 1] = Fout[fout_ptr + 1] - num21; num11 += fstride * 2; num10 += fstride * 4; num9 += fstride * 6; Fout[fout_ptr] += num20; Fout[fout_ptr + 1] += num21; Fout[num6] = num18 + num23; Fout[num6 + 1] = num19 - num22; Fout[num8] = num18 - num23; Fout[num8 + 1] = num19 + num22; fout_ptr += 2; num6 += 2; num7 += 2; num8 += 2; } } } internal static void kf_bfly3(Span Fout, int fout_ptr, int fstride, FFTState st, int m, int N, int mm) { int num = 2 * m; int num2 = 4 * m; int num3 = fout_ptr; for (int i = 0; i < N; i++) { fout_ptr = num3 + 2 * i * mm; int num5; int num4 = (num5 = 0); int num6 = m; do { int num7 = S_MUL(Fout[fout_ptr + num], st.twiddles[num4]) - S_MUL(Fout[fout_ptr + num + 1], st.twiddles[num4 + 1]); int num8 = S_MUL(Fout[fout_ptr + num], st.twiddles[num4 + 1]) + S_MUL(Fout[fout_ptr + num + 1], st.twiddles[num4]); int num9 = S_MUL(Fout[fout_ptr + num2], st.twiddles[num5]) - S_MUL(Fout[fout_ptr + num2 + 1], st.twiddles[num5 + 1]); int num10 = S_MUL(Fout[fout_ptr + num2], st.twiddles[num5 + 1]) + S_MUL(Fout[fout_ptr + num2 + 1], st.twiddles[num5]); int num11 = num7 + num9; int num12 = num8 + num10; int a = num7 - num9; int a2 = num8 - num10; num4 += fstride * 2; num5 += fstride * 4; Fout[fout_ptr + num] = Fout[fout_ptr] - HALF_OF(num11); Fout[fout_ptr + num + 1] = Fout[fout_ptr + 1] - HALF_OF(num12); a = S_MUL(a, -28378); a2 = S_MUL(a2, -28378); Fout[fout_ptr] += num11; Fout[fout_ptr + 1] += num12; Fout[fout_ptr + num2] = Fout[fout_ptr + num] + a2; Fout[fout_ptr + num2 + 1] = Fout[fout_ptr + num + 1] - a; Fout[fout_ptr + num] -= a2; Fout[fout_ptr + num + 1] += a; fout_ptr += 2; } while (--num6 != 0); } } internal static void kf_bfly5(Span Fout, int fout_ptr, int fstride, FFTState st, int m, int N, int mm) { int num = fout_ptr; short b = 10126; short b2 = -31164; short b3 = -26510; short b4 = -19261; for (int i = 0; i < N; i++) { int num3; int num4; int num5; int num2 = (num3 = (num4 = (num5 = 0))); fout_ptr = num + 2 * i * mm; int num6 = fout_ptr; int num7 = fout_ptr + 2 * m; int num8 = fout_ptr + 4 * m; int num9 = fout_ptr + 6 * m; int num10 = fout_ptr + 8 * m; for (int j = 0; j < m; j++) { int num11 = Fout[num6]; int num12 = Fout[num6 + 1]; int num13 = S_MUL(Fout[num7], st.twiddles[num2]) - S_MUL(Fout[num7 + 1], st.twiddles[num2 + 1]); int num14 = S_MUL(Fout[num7], st.twiddles[num2 + 1]) + S_MUL(Fout[num7 + 1], st.twiddles[num2]); int num15 = S_MUL(Fout[num8], st.twiddles[num3]) - S_MUL(Fout[num8 + 1], st.twiddles[num3 + 1]); int num16 = S_MUL(Fout[num8], st.twiddles[num3 + 1]) + S_MUL(Fout[num8 + 1], st.twiddles[num3]); int num17 = S_MUL(Fout[num9], st.twiddles[num4]) - S_MUL(Fout[num9 + 1], st.twiddles[num4 + 1]); int num18 = S_MUL(Fout[num9], st.twiddles[num4 + 1]) + S_MUL(Fout[num9 + 1], st.twiddles[num4]); int num19 = S_MUL(Fout[num10], st.twiddles[num5]) - S_MUL(Fout[num10 + 1], st.twiddles[num5 + 1]); int num20 = S_MUL(Fout[num10], st.twiddles[num5 + 1]) + S_MUL(Fout[num10 + 1], st.twiddles[num5]); num2 += 2 * fstride; num3 += 4 * fstride; num4 += 6 * fstride; num5 += 8 * fstride; int num21 = num13 + num19; int num22 = num14 + num20; int a = num13 - num19; int a2 = num14 - num20; int num23 = num15 + num17; int num24 = num16 + num18; int a3 = num15 - num17; int a4 = num16 - num18; Fout[num6] += num21 + num23; Fout[num6 + 1] += num22 + num24; int num25 = num11 + S_MUL(num21, b) + S_MUL(num23, b3); int num26 = num12 + S_MUL(num22, b) + S_MUL(num24, b3); int num27 = S_MUL(a2, b2) + S_MUL(a4, b4); int num28 = -S_MUL(a, b2) - S_MUL(a3, b4); Fout[num7] = num25 - num27; Fout[num7 + 1] = num26 - num28; Fout[num10] = num25 + num27; Fout[num10 + 1] = num26 + num28; int num29 = num11 + S_MUL(num21, b3) + S_MUL(num23, b); int num30 = num12 + S_MUL(num22, b3) + S_MUL(num24, b); int num31 = -S_MUL(a2, b4) + S_MUL(a4, b2); int num32 = S_MUL(a, b4) - S_MUL(a3, b2); Fout[num8] = num29 + num31; Fout[num8 + 1] = num30 + num32; Fout[num9] = num29 - num31; Fout[num9 + 1] = num30 - num32; num6 += 2; num7 += 2; num8 += 2; num9 += 2; num10 += 2; } } } internal static void opus_fft_impl(FFTState st, Span fout, int fout_ptr) { int[] array = new int[8]; int num = ((st.shift > 0) ? st.shift : 0); array[0] = 1; int num2 = 0; int num4; do { int num3 = st.factors[2 * num2]; num4 = st.factors[2 * num2 + 1]; array[num2 + 1] = array[num2] * num3; num2++; } while (num4 != 1); num4 = st.factors[2 * num2 - 1]; for (int num5 = num2 - 1; num5 >= 0; num5--) { int num6 = ((num5 == 0) ? 1 : st.factors[2 * num5 - 1]); switch (st.factors[2 * num5]) { case 2: kf_bfly2(fout, fout_ptr, num4, array[num5]); break; case 4: kf_bfly4(fout, fout_ptr, array[num5] << num, st, num4, array[num5], num6); break; case 3: kf_bfly3(fout, fout_ptr, array[num5] << num, st, num4, array[num5], num6); break; case 5: kf_bfly5(fout, fout_ptr, array[num5] << num, st, num4, array[num5], num6); break; } num4 = num6; } } internal static void opus_fft(FFTState st, int[] fin, int[] fout) { int shift = st.scale_shift - 1; short scale = st.scale; for (int i = 0; i < st.nfft; i++) { fout[2 * st.bitrev[i]] = Inlines.SHR32(Inlines.MULT16_32_Q16(scale, fin[2 * i]), shift); fout[2 * st.bitrev[i] + 1] = Inlines.SHR32(Inlines.MULT16_32_Q16(scale, fin[2 * i + 1]), shift); } opus_fft_impl(st, fout, 0); } } internal static class Laplace { private const int LAPLACE_LOG_MINP = 0; private const uint LAPLACE_MINP = 1u; private const int LAPLACE_NMIN = 16; internal static uint ec_laplace_get_freq1(uint fs0, int decay) { return (uint)((32736 - fs0) * (16384 - decay) >> 15); } internal static void ec_laplace_encode(EntropyCoder enc, Span encodedData, ref int value, uint fs, int decay) { int num = value; uint num2 = 0u; if (num != 0) { int num3 = 0 - ((num < 0) ? 1 : 0); num = (num + num3) ^ num3; num2 = fs; fs = ec_laplace_get_freq1(fs, decay); int num4 = 1; while (fs != 0 && num4 < num) { fs *= 2; num2 += fs + 2; fs = (uint)(fs * decay >> 15); num4++; } if (fs == 0) { int num5 = (int)(32768 - num2 + 1 - 1); num5 = num5 - num3 >> 1; int num6 = Inlines.IMIN(num - num4, num5 - 1); num2 += (uint)(2 * num6 + 1 + num3); fs = Inlines.IMIN(1u, 32768 - num2); value = (num4 + num6 + num3) ^ num3; } else { fs++; num2 += (uint)(int)(fs & ~num3); } } enc.encode_bin(encodedData, num2, num2 + fs, 15u); } internal static int ec_laplace_decode(EntropyCoder dec, ReadOnlySpan encodedData, uint fs, int decay) { int num = 0; uint num2 = dec.decode_bin(15u); uint num3 = 0u; if (num2 >= fs) { num++; num3 = fs; fs = ec_laplace_get_freq1(fs, decay) + 1; while (fs > 1 && num2 >= num3 + 2 * fs) { fs *= 2; num3 += fs; fs = (uint)((fs - 2) * decay >> 15); fs++; num++; } if (fs <= 1) { int num4 = (int)(num2 - num3) >> 1; num += num4; num3 += (uint)(2 * num4); } if (num2 < num3 + fs) { num = -num; } else { num3 += fs; } } dec.dec_update(encodedData, num3, Inlines.IMIN(num3 + fs, 32768u), 32768u); return num; } } internal static class MDCT { internal static void clt_mdct_forward(MDCTLookup l, Span input, int input_ptr, Span output, int output_ptr, int[] window, int overlap, int shift, int stride) { FFTState fFTState = l.kfft[shift]; int num = 0; int shift2 = fFTState.scale_shift - 1; int scale = fFTState.scale; int num2 = l.n; short[] trig = l.trig; int i; for (i = 0; i < shift; i++) { num2 >>= 1; num += num2; } int num3 = num2 >> 1; int num4 = num2 >> 2; int[] array = new int[num3]; int[] array2 = new int[num4 * 2]; int num5 = input_ptr + (overlap >> 1); int num6 = input_ptr + num3 - 1 + (overlap >> 1); int num7 = 0; int num8 = overlap >> 1; int num9 = (overlap >> 1) - 1; for (i = 0; i < overlap + 3 >> 2; i++) { array[num7++] = Inlines.MULT16_32_Q15(window[num9], input[num5 + num3]) + Inlines.MULT16_32_Q15(window[num8], input[num6]); array[num7++] = Inlines.MULT16_32_Q15(window[num8], input[num5]) - Inlines.MULT16_32_Q15(window[num9], input[num6 - num3]); num5 += 2; num6 -= 2; num8 += 2; num9 -= 2; } num8 = 0; num9 = overlap - 1; for (; i < num4 - (overlap + 3 >> 2); i++) { array[num7++] = input[num6]; array[num7++] = input[num5]; num5 += 2; num6 -= 2; } for (; i < num4; i++) { array[num7++] = Inlines.MULT16_32_Q15(window[num9], input[num6]) - Inlines.MULT16_32_Q15(window[num8], input[num5 - num3]); array[num7++] = Inlines.MULT16_32_Q15(window[num9], input[num5]) + Inlines.MULT16_32_Q15(window[num8], input[num6 + num3]); num5 += 2; num6 -= 2; num8 += 2; num9 -= 2; } int num10 = 0; int num11 = num; for (i = 0; i < num4; i++) { short b = trig[num11 + i]; short b2 = trig[num11 + num4 + i]; int a = array[num10++]; int a2 = array[num10++]; int b3 = KissFFT.S_MUL(a, b) - KissFFT.S_MUL(a2, b2); int b4 = KissFFT.S_MUL(a2, b) + KissFFT.S_MUL(a, b2); array2[2 * fFTState.bitrev[i]] = Inlines.PSHR32(Inlines.MULT16_32_Q16(scale, b3), shift2); array2[2 * fFTState.bitrev[i] + 1] = Inlines.PSHR32(Inlines.MULT16_32_Q16(scale, b4), shift2); } KissFFT.opus_fft_impl(fFTState, array2, 0); int num12 = 0; int num13 = output_ptr; int num14 = output_ptr + stride * (num3 - 1); int num15 = num; for (i = 0; i < num4; i++) { int num16 = KissFFT.S_MUL(array2[num12 + 1], trig[num15 + num4 + i]) - KissFFT.S_MUL(array2[num12], trig[num15 + i]); int num17 = KissFFT.S_MUL(array2[num12], trig[num15 + num4 + i]) + KissFFT.S_MUL(array2[num12 + 1], trig[num15 + i]); output[num13] = num16; output[num14] = num17; num12 += 2; num13 += 2 * stride; num14 -= 2 * stride; } } internal static void clt_mdct_backward(MDCTLookup l, Span input, int input_ptr, Span output, int output_ptr, int[] window, int overlap, int shift, int stride) { int num = 0; int num2 = l.n; for (int i = 0; i < shift; i++) { num2 >>= 1; num += num2; } int num3 = num2 >> 1; int num4 = num2 >> 2; int num5 = input_ptr + stride * (num3 - 1); int num6 = output_ptr + (overlap >> 1); short[] bitrev = l.kfft[shift].bitrev; int num7 = 0; for (int i = 0; i < num4; i++) { int num8 = bitrev[num7++]; int num9 = num6 + 2 * num8; output[num9 + 1] = KissFFT.S_MUL(input[num5], l.trig[num + i]) + KissFFT.S_MUL(input[input_ptr], l.trig[num + num4 + i]); output[num9] = KissFFT.S_MUL(input[input_ptr], l.trig[num + i]) - KissFFT.S_MUL(input[num5], l.trig[num + num4 + i]); input_ptr += 2 * stride; num5 -= 2 * stride; } KissFFT.opus_fft_impl(l.kfft[shift], output, output_ptr + (overlap >> 1)); int num10 = output_ptr + (overlap >> 1); int num11 = output_ptr + (overlap >> 1) + num3 - 2; int num12 = num; int num13 = num12 + num4 - 1; int num14 = num12 + num3 - 1; for (int i = 0; i < num4 + 1 >> 1; i++) { int a = output[num10 + 1]; int a2 = output[num10]; short b = l.trig[num12 + i]; short b2 = l.trig[num12 + num4 + i]; int num15 = KissFFT.S_MUL(a, b) + KissFFT.S_MUL(a2, b2); int num16 = KissFFT.S_MUL(a, b2) - KissFFT.S_MUL(a2, b); int a3 = output[num11 + 1]; a2 = output[num11]; output[num10] = num15; output[num11 + 1] = num16; b = l.trig[num13 - i]; b2 = l.trig[num14 - i]; num15 = KissFFT.S_MUL(a3, b) + KissFFT.S_MUL(a2, b2); num16 = KissFFT.S_MUL(a3, b2) - KissFFT.S_MUL(a2, b); output[num11] = num15; output[num10 + 1] = num16; num10 += 2; num11 -= 2; } int index = output_ptr + overlap - 1; num11 = output_ptr; int num17 = 0; int num18 = overlap - 1; for (int i = 0; i < overlap / 2; i++) { int b3 = output[index]; int b4 = output[num11]; output[num11++] = Inlines.MULT16_32_Q15(window[num18], b4) - Inlines.MULT16_32_Q15(window[num17], b3); output[index--] = Inlines.MULT16_32_Q15(window[num17], b4) + Inlines.MULT16_32_Q15(window[num18], b3); num17++; num18--; } } } internal static class Pitch { private static readonly int[] second_check = new int[16] { 0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2 }; internal static void find_best_pitch(Span xcorr, Span y, int len, int max_pitch, int[] best_pitch, int yshift, int maxcorr) { int num = 1; int shift = Inlines.celt_ilog2(maxcorr) - 14; int num2 = -1; int a = -1; int num3 = 0; int b = 0; best_pitch[0] = 0; best_pitch[1] = 1; for (int i = 0; i < len; i++) { num = Inlines.ADD32(num, Inlines.SHR32(Inlines.MULT16_16(y[i], y[i]), yshift)); } for (int j = 0; j < max_pitch; j++) { if (xcorr[j] > 0) { short num4 = Inlines.EXTRACT16(Inlines.VSHR32(xcorr[j], shift)); int num5 = Inlines.MULT16_16_Q15((int)num4, (int)num4); if (Inlines.MULT16_32_Q15(num5, b) > Inlines.MULT16_32_Q15(a, num)) { if (Inlines.MULT16_32_Q15(num5, num3) > Inlines.MULT16_32_Q15(num2, num)) { a = num2; b = num3; best_pitch[1] = best_pitch[0]; num2 = num5; num3 = num; best_pitch[0] = j; } else { a = num5; b = num; best_pitch[1] = j; } } } num += Inlines.SHR32(Inlines.MULT16_16(y[j + len], y[j + len]), yshift) - Inlines.SHR32(Inlines.MULT16_16(y[j], y[j]), yshift); num = Inlines.MAX32(1, num); } } internal static void celt_fir5(int[] x, int[] num, int[] y, int N, int[] mem) { int a = num[0]; int a2 = num[1]; int a3 = num[2]; int a4 = num[3]; int a5 = num[4]; int num2 = mem[0]; int num3 = mem[1]; int num4 = mem[2]; int num5 = mem[3]; int num6 = mem[4]; for (int i = 0; i < N; i++) { int c = Inlines.SHL32(Inlines.EXTEND32(x[i]), 12); c = Inlines.MAC16_16(c, a, num2); c = Inlines.MAC16_16(c, a2, num3); c = Inlines.MAC16_16(c, a3, num4); c = Inlines.MAC16_16(c, a4, num5); c = Inlines.MAC16_16(c, a5, num6); num6 = num5; num5 = num4; num4 = num3; num3 = num2; num2 = x[i]; y[i] = Inlines.ROUND16(c, 12); } mem[0] = num2; mem[1] = num3; mem[2] = num4; mem[3] = num5; mem[4] = num6; } internal static void pitch_downsample(int[][] x, int[] x_lp, int len, int C) { int[] array = new int[5]; int b = 32767; int[] array2 = new int[4]; int[] mem = new int[5]; int[] array3 = new int[5]; int a = 26214; int num = Inlines.celt_maxabs32(x[0], 0, len); if (C == 2) { int b2 = Inlines.celt_maxabs32(x[1], 0, len); num = Inlines.MAX32(num, b2); } if (num < 1) { num = 1; } int num2 = Inlines.celt_ilog2(num) - 10; if (num2 < 0) { num2 = 0; } if (C == 2) { num2++; } int num3 = len >> 1; for (int i = 1; i < num3; i++) { x_lp[i] = Inlines.SHR32(Inlines.HALF32(Inlines.HALF32(x[0][2 * i - 1] + x[0][2 * i + 1]) + x[0][2 * i]), num2); } x_lp[0] = Inlines.SHR32(Inlines.HALF32(Inlines.HALF32(x[0][1]) + x[0][0]), num2); if (C == 2) { for (int i = 1; i < num3; i++) { x_lp[i] += Inlines.SHR32(Inlines.HALF32(Inlines.HALF32(x[1][2 * i - 1] + x[1][2 * i + 1]) + x[1][2 * i]), num2); } x_lp[0] += Inlines.SHR32(Inlines.HALF32(Inlines.HALF32(x[1][1]) + x[1][0]), num2); } Autocorrelation._celt_autocorr(x_lp, array, null, 0, 4, num3); array[0] += Inlines.SHR32(array[0], 13); for (int i = 1; i <= 4; i++) { array[i] -= Inlines.MULT16_32_Q15(2 * i * i, array[i]); } CeltLPC.celt_lpc(array2, array, 4); for (int i = 0; i < 4; i++) { b = Inlines.MULT16_16_Q15(29491, b); array2[i] = Inlines.MULT16_16_Q15(array2[i], b); } array3[0] = array2[0] + 3277; array3[1] = array2[1] + Inlines.MULT16_16_Q15(a, array2[0]); array3[2] = array2[2] + Inlines.MULT16_16_Q15(a, array2[1]); array3[3] = array2[3] + Inlines.MULT16_16_Q15(a, array2[2]); array3[4] = Inlines.MULT16_16_Q15(a, array2[3]); celt_fir5(x_lp, array3, x_lp, num3, mem); } internal static void pitch_search(Span x_lp, int x_lp_ptr, int[] y, int len, int max_pitch, out int pitch) { int[] array = new int[2]; int num = 0; int num2 = len + max_pitch; int[] array2 = new int[len >> 2]; int[] array3 = new int[num2 >> 2]; int[] array4 = new int[max_pitch >> 1]; for (int i = 0; i < len >> 2; i++) { array2[i] = x_lp[x_lp_ptr + 2 * i]; } for (int i = 0; i < num2 >> 2; i++) { array3[i] = y[2 * i]; } int a = Inlines.celt_maxabs32(array2, len >> 2); int b = Inlines.celt_maxabs32(array3, num2 >> 2); num = Inlines.celt_ilog2(Inlines.MAX32(1, Inlines.MAX32(a, b))) - 11; if (num > 0) { for (int i = 0; i < len >> 2; i++) { array2[i] = Inlines.SHR16(array2[i], num); } for (int i = 0; i < num2 >> 2; i++) { array3[i] = Inlines.SHR16(array3[i], num); } num *= 2; } else { num = 0; } int maxcorr = CeltPitchXCorr.pitch_xcorr(array2, 0, array3, 0, array4, len >> 2, max_pitch >> 2); find_best_pitch(array4, array3, len >> 2, max_pitch >> 2, array, 0, maxcorr); maxcorr = 1; for (int j = 0; j < max_pitch >> 1; j++) { array4[j] = 0; if (Inlines.abs(j - 2 * array[0]) <= 2 || Inlines.abs(j - 2 * array[1]) <= 2) { int num3 = 0; for (int i = 0; i < len >> 1; i++) { num3 += Inlines.SHR32(Inlines.MULT16_16(x_lp[x_lp_ptr + i], y[j + i]), num); } array4[j] = Inlines.MAX32(-1, num3); maxcorr = Inlines.MAX32(maxcorr, num3); } } find_best_pitch(array4, y, len >> 1, max_pitch >> 1, array, num + 1, maxcorr); int num7; if (array[0] > 0 && array[0] < (max_pitch >> 1) - 1) { int num4 = array4[array[0] - 1]; int num5 = array4[array[0]]; int num6 = array4[array[0] + 1]; num7 = ((num6 - num4 > Inlines.MULT16_32_Q15((short)22938, num5 - num4)) ? 1 : ((num4 - num6 > Inlines.MULT16_32_Q15((short)22938, num5 - num6)) ? (-1) : 0)); } else { num7 = 0; } pitch = 2 * array[0] - num7; } internal static int remove_doubling(int[] x, int maxperiod, int minperiod, int N, ref int T0_, int prev_period, int prev_gain) { Span span = new int[3]; int num = minperiod; maxperiod /= 2; minperiod /= 2; T0_ /= 2; prev_period /= 2; N /= 2; int num2 = maxperiod; if (T0_ >= maxperiod) { T0_ = maxperiod - 1; } int num4; int num3 = (num4 = T0_); Span span2 = new int[maxperiod + 1]; Span span3 = MemoryExtensions.AsSpan(x); Span x2 = span3.Slice(num2); span3 = MemoryExtensions.AsSpan(x); Span y = span3.Slice(num2); span3 = MemoryExtensions.AsSpan(x); Kernels.dual_inner_prod(x2, y, span3.Slice(num2 - num4), N, out var xy, out var xy2); span2[0] = xy; int num5 = xy; for (int i = 1; i <= maxperiod; i++) { int num6 = num2 - i; num5 = num5 + Inlines.MULT16_16(x[num6], x[num6]) - Inlines.MULT16_16(x[num6 + N], x[num6 + N]); span2[i] = Inlines.MAX32(0, num5); } num5 = span2[num4]; int b = xy2; int num7 = num5; int num8 = 1 + Inlines.HALF32(Inlines.MULT32_32_Q31(xy, num5)); int num9 = Inlines.celt_ilog2(num8) >> 1; int num10 = Inlines.VSHR32(Inlines.MULT16_32_Q15(Inlines.celt_rsqrt_norm(Inlines.VSHR32(num8, 2 * (num9 - 7))), xy2), num9 + 1); int b2 = num10; for (int j = 2; j <= 15; j++) { int num11 = 0; int num12 = Inlines.celt_udiv(2 * num4 + j, 2 * j); if (num12 < minperiod) { break; } int num13 = ((j != 2) ? Inlines.celt_udiv(2 * second_check[j] * num4 + j, 2 * j) : ((num12 + num4 <= maxperiod) ? (num4 + num12) : num4)); span3 = MemoryExtensions.AsSpan(x); Span x3 = span3.Slice(num2); span3 = MemoryExtensions.AsSpan(x); Span y2 = span3.Slice(num2 - num12); span3 = MemoryExtensions.AsSpan(x); Kernels.dual_inner_prod(x3, y2, span3.Slice(num2 - num13), N, out xy2, out var xy3); xy2 += xy3; num5 = span2[num12] + span2[num13]; int num14 = 1 + Inlines.MULT32_32_Q31(xy, num5); int num15 = Inlines.celt_ilog2(num14) >> 1; int num16 = Inlines.VSHR32(Inlines.MULT16_32_Q15(Inlines.celt_rsqrt_norm(Inlines.VSHR32(num14, 2 * (num15 - 7))), xy2), num15 + 1); num11 = ((Inlines.abs(num12 - prev_period) <= 1) ? prev_gain : ((Inlines.abs(num12 - prev_period) <= 2 && 5 * j * j < num4) ? Inlines.HALF16(prev_gain) : 0)); int num17 = Inlines.MAX16(9830, Inlines.MULT16_16_Q15(22938, b2) - num11); if (num12 < 3 * minperiod) { num17 = Inlines.MAX16(13107, Inlines.MULT16_16_Q15(27853, b2) - num11); } else if (num12 < 2 * minperiod) { num17 = Inlines.MAX16(16384, Inlines.MULT16_16_Q15(29491, b2) - num11); } if (num16 > num17) { b = xy2; num7 = num5; num3 = num12; num10 = num16; } } b = Inlines.MAX32(0, b); int num18 = ((num7 > b) ? Inlines.SHR32(Inlines.frac_div32(b, num7 + 1), 16) : 32767); for (int j = 0; j < 3; j++) { ref int reference = ref span[j]; span3 = MemoryExtensions.AsSpan(x); Span x4 = span3.Slice(num2); span3 = MemoryExtensions.AsSpan(x); reference = Kernels.celt_inner_prod(x4, span3.Slice(num2 - (num3 + j - 1)), N); } int num19 = ((span[2] - span[0] > Inlines.MULT16_32_Q15((short)22938, span[1] - span[0])) ? 1 : ((span[0] - span[2] > Inlines.MULT16_32_Q15((short)22938, span[1] - span[2])) ? (-1) : 0)); if (num18 > num10) { num18 = num10; } T0_ = 2 * num3 + num19; if (T0_ < num) { T0_ = num; } return num18; } } internal static class QuantizeBands { private static readonly int[] pred_coef = new int[4] { 29440, 26112, 21248, 16384 }; private static readonly int[] beta_coef = new int[4] { 30147, 22282, 12124, 6554 }; private static readonly int beta_intra = 4915; private static byte[] small_energy_icdf = new byte[3] { 2, 1, 0 }; internal static int loss_distortion(int[][] eBands, int[][] oldEBands, int start, int end, int len, int C) { int num = 0; int num2 = 0; do { for (int i = start; i < end; i++) { int num3 = Inlines.SUB16(Inlines.SHR16(eBands[num2][i], 3), Inlines.SHR16(oldEBands[num2][i], 3)); num = Inlines.MAC16_16(num, num3, num3); } } while (++num2 < C); return Inlines.MIN32(200, Inlines.SHR32(num, 14)); } internal static int quant_coarse_energy_impl(CeltMode m, int start, int end, int[][] eBands, int[][] oldEBands, int budget, int tell, byte[] prob_model, int[][] error, EntropyCoder enc, Span encodedData, int C, int LM, int intra, int max_decay, int lfe) { int num = 0; int[] array = new int[2]; if (tell + 3 <= budget) { enc.enc_bit_logp(encodedData, intra, 3u); } int a; int a2; if (intra != 0) { a = 0; a2 = beta_intra; } else { a2 = beta_coef[LM]; a = pred_coef[LM]; } for (int i = start; i < end; i++) { int num2 = 0; do { int num3 = eBands[num2][i]; int b = Inlines.MAX16(-9216, oldEBands[num2][i]); int num4 = Inlines.SHL32(Inlines.EXTEND32(num3), 7) - Inlines.PSHR32(Inlines.MULT16_16(a, b), 8) - array[num2]; int value = num4 + 65536 >> 17; int num5 = Inlines.EXTRACT16(Inlines.MAX32(-28672, Inlines.SUB32(oldEBands[num2][i], max_decay))); if (value < 0 && num3 < num5) { value += Inlines.SHR16(Inlines.SUB16(num5, num3), 10); if (value > 0) { value = 0; } } int num6 = value; tell = enc.tell(); int num7 = budget - tell - 3 * C * (end - i); if (i != start && num7 < 30) { if (num7 < 24) { value = Inlines.IMIN(1, value); } if (num7 < 16) { value = Inlines.IMAX(-1, value); } } if (lfe != 0 && i >= 2) { value = Inlines.IMIN(value, 0); } if (budget - tell >= 15) { int num8 = 2 * Inlines.IMIN(i, 20); Laplace.ec_laplace_encode(enc, encodedData, ref value, (uint)(prob_model[num8] << 7), prob_model[num8 + 1] << 6); } else if (budget - tell >= 2) { value = Inlines.IMAX(-1, Inlines.IMIN(value, 1)); enc.enc_icdf(encodedData, (2 * value) ^ (0 - ((value < 0) ? 1 : 0)), small_energy_icdf, 2u); } else if (budget - tell >= 1) { value = Inlines.IMIN(0, value); enc.enc_bit_logp(encodedData, -value, 1u); } else { value = -1; } error[num2][i] = Inlines.PSHR32(num4, 7) - Inlines.SHL16(value, 10); num += Inlines.abs(num6 - value); int a3 = Inlines.SHL32(value, 10); int b2 = Inlines.PSHR32(Inlines.MULT16_16(a, b), 8) + array[num2] + Inlines.SHL32(a3, 7); b2 = Inlines.MAX32(-3670016, b2); oldEBands[num2][i] = Inlines.PSHR32(b2, 7); array[num2] = array[num2] + Inlines.SHL32(a3, 7) - Inlines.MULT16_16(a2, Inlines.PSHR32(a3, 8)); } while (++num2 < C); } if (lfe == 0) { return num; } return 0; } internal static void quant_coarse_energy(CeltMode m, int start, int end, int effEnd, int[][] eBands, int[][] oldEBands, uint budget, int[][] error, EntropyCoder enc, Span encodedData, int C, int LM, int nbAvailableBytes, int force_intra, ref int delayedIntra, int two_pass, int loss_rate, int lfe) { EntropyCoder entropyCoder = new EntropyCoder(); int num = 0; int num2 = ((force_intra != 0 || (two_pass == 0 && delayedIntra > 2 * C * (end - start) && nbAvailableBytes > (end - start) * C)) ? 1 : 0); int num3 = (int)(budget * delayedIntra * loss_rate / (C * 512)); int num4 = loss_distortion(eBands, oldEBands, start, effEnd, m.nbEBands, C); uint num5 = (uint)enc.tell(); if (num5 + 3 > budget) { two_pass = (num2 = 0); } int num6 = 16384; if (end - start > 10) { num6 = Inlines.MIN32(num6, Inlines.SHL32(nbAvailableBytes, 7)); } if (lfe != 0) { num6 = 3072; } entropyCoder.Assign(enc); int[][] array = Arrays.InitTwoDimensionalArray(C, m.nbEBands); int[][] array2 = Arrays.InitTwoDimensionalArray(C, m.nbEBands); Arrays.MemCopy(oldEBands[0], 0, array[0], 0, m.nbEBands); if (C == 2) { Arrays.MemCopy(oldEBands[1], 0, array[1], 0, m.nbEBands); } if (two_pass != 0 || num2 != 0) { num = quant_coarse_energy_impl(m, start, end, eBands, array, (int)budget, (int)num5, Tables.e_prob_model[LM][1], array2, enc, encodedData, C, LM, 1, num6, lfe); } if (num2 == 0) { EntropyCoder entropyCoder2 = new EntropyCoder(); byte[] array3 = null; int num7 = (int)enc.tell_frac(); entropyCoder2.Assign(enc); uint num8 = entropyCoder.range_bytes(); uint num9 = entropyCoder2.range_bytes(); int start2 = (int)num8; uint num10 = num9 - num8; if (num10 != 0) { array3 = new byte[num10]; encodedData.Slice(start2, (int)num10).CopyTo(array3); } enc.Assign(entropyCoder); int num11 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, (int)budget, (int)num5, Tables.e_prob_model[LM][num2], error, enc, encodedData, C, LM, 0, num6, lfe); if (two_pass != 0 && (num < num11 || (num == num11 && (int)enc.tell_frac() + num3 > num7))) { enc.Assign(entropyCoder2); if (array3 != null) { MemoryExtensions.AsSpan(array3, 0, (int)(num9 - num8)).CopyTo(encodedData.Slice(start2)); } Arrays.MemCopy(array[0], 0, oldEBands[0], 0, m.nbEBands); Arrays.MemCopy(array2[0], 0, error[0], 0, m.nbEBands); if (C == 2) { Arrays.MemCopy(array[1], 0, oldEBands[1], 0, m.nbEBands); Arrays.MemCopy(array2[1], 0, error[1], 0, m.nbEBands); } num2 = 1; } } else { Arrays.MemCopy(array[0], 0, oldEBands[0], 0, m.nbEBands); Arrays.MemCopy(array2[0], 0, error[0], 0, m.nbEBands); if (C == 2) { Arrays.MemCopy(array[1], 0, oldEBands[1], 0, m.nbEBands); Arrays.MemCopy(array2[1], 0, error[1], 0, m.nbEBands); } } if (num2 != 0) { delayedIntra = num4; } else { delayedIntra = Inlines.ADD32(Inlines.MULT16_32_Q15(Inlines.MULT16_16_Q15(pred_coef[LM], pred_coef[LM]), delayedIntra), num4); } } internal static void quant_fine_energy(CeltMode m, int start, int end, int[][] oldEBands, int[][] error, int[] fine_quant, EntropyCoder enc, Span encodedData, int C) { for (int i = start; i < end; i++) { int num = 1 << fine_quant[i]; if (fine_quant[i] <= 0) { continue; } int num2 = 0; do { int num3 = error[num2][i] + 512 >> 10 - fine_quant[i]; if (num3 > num - 1) { num3 = num - 1; } if (num3 < 0) { num3 = 0; } enc.enc_bits(encodedData, (uint)num3, (uint)fine_quant[i]); int num4 = Inlines.SUB16(Inlines.SHR32(Inlines.SHL32(num3, 10) + 512, fine_quant[i]), 512); oldEBands[num2][i] += num4; error[num2][i] -= num4; } while (++num2 < C); } } internal static void quant_energy_finalise(CeltMode m, int start, int end, int[][] oldEBands, int[][] error, int[] fine_quant, int[] fine_priority, int bits_left, EntropyCoder enc, Span encodedData, int C) { for (int i = 0; i < 2; i++) { for (int j = start; j < end; j++) { if (bits_left < C) { break; } if (fine_quant[j] < 8 && fine_priority[j] == i) { int num = 0; do { int num2 = ((error[num][j] >= 0) ? 1 : 0); enc.enc_bits(encodedData, (uint)num2, 1u); int num3 = Inlines.SHR16(Inlines.SHL16(num2, 10) - 512, fine_quant[j] + 1); oldEBands[num][j] += num3; bits_left--; } while (++num < C); } } } } internal static void unquant_coarse_energy(CeltMode m, int start, int end, int[] oldEBands, int intra, EntropyCoder dec, ReadOnlySpan encodedData, int C, int LM) { byte[] array = Tables.e_prob_model[LM][intra]; int[] array2 = new int[2]; int a; int a2; if (intra != 0) { a = 0; a2 = beta_intra; } else { a2 = beta_coef[LM]; a = pred_coef[LM]; } int num = (int)(dec.storage * 8); for (int i = start; i < end; i++) { int num2 = 0; do { int num3 = dec.tell(); int a3; if (num - num3 >= 15) { int num4 = 2 * Inlines.IMIN(i, 20); a3 = Laplace.ec_laplace_decode(dec, encodedData, (uint)(array[num4] << 7), array[num4 + 1] << 6); } else if (num - num3 < 2) { a3 = ((num - num3 < 1) ? (-1) : (-dec.dec_bit_logp(encodedData, 1u))); } else { a3 = dec.dec_icdf(encodedData, small_energy_icdf, 2u); a3 = (a3 >> 1) ^ -(a3 & 1); } int a4 = Inlines.SHL32(a3, 10); oldEBands[i + num2 * m.nbEBands] = Inlines.MAX16(-9216, oldEBands[i + num2 * m.nbEBands]); int b = Inlines.PSHR32(Inlines.MULT16_16(a, oldEBands[i + num2 * m.nbEBands]), 8) + array2[num2] + Inlines.SHL32(a4, 7); b = Inlines.MAX32(-3670016, b); oldEBands[i + num2 * m.nbEBands] = Inlines.PSHR32(b, 7); array2[num2] = array2[num2] + Inlines.SHL32(a4, 7) - Inlines.MULT16_16(a2, Inlines.PSHR32(a4, 8)); } while (++num2 < C); } } internal static void unquant_fine_energy(CeltMode m, int start, int end, int[] oldEBands, int[] fine_quant, EntropyCoder dec, ReadOnlySpan encodedData, int C) { for (int i = start; i < end; i++) { if (fine_quant[i] > 0) { int num = 0; do { int num2 = Inlines.SUB16(Inlines.SHR32(Inlines.SHL32((int)dec.dec_bits(encodedData, (uint)fine_quant[i]), 10) + 512, fine_quant[i]), 512); oldEBands[i + num * m.nbEBands] += num2; } while (++num < C); } } } internal static void unquant_energy_finalise(CeltMode m, int start, int end, int[] oldEBands, int[] fine_quant, int[] fine_priority, int bits_left, EntropyCoder dec, ReadOnlySpan encodedData, int C) { for (int i = 0; i < 2; i++) { for (int j = start; j < end; j++) { if (bits_left < C) { break; } if (fine_quant[j] < 8 && fine_priority[j] == i) { int num = 0; do { int num2 = Inlines.SHR16(Inlines.SHL16((int)dec.dec_bits(encodedData, 1u), 10) - 512, fine_quant[j] + 1); oldEBands[j + num * m.nbEBands] += num2; bits_left--; } while (++num < C); } } } } internal static void amp2Log2(CeltMode m, int effEnd, int end, int[][] bandE, int[][] bandLogE, int C) { int num = 0; do { for (int i = 0; i < effEnd; i++) { bandLogE[num][i] = Inlines.celt_log2(Inlines.SHL32(bandE[num][i], 2)) - Inlines.SHL16((int)Tables.eMeans[i], 6); } for (int i = effEnd; i < end; i++) { bandLogE[num][i] = -14336; } } while (++num < C); } internal static void amp2Log2(CeltMode m, int effEnd, int end, int[] bandE, Span bandLogE, int bandLogE_ptr, int C) { int num = 0; do { for (int i = 0; i < effEnd; i++) { bandLogE[bandLogE_ptr + num * m.nbEBands + i] = Inlines.celt_log2(Inlines.SHL32(bandE[i + num * m.nbEBands], 2)) - Inlines.SHL16((int)Tables.eMeans[i], 6); } for (int i = effEnd; i < end; i++) { bandLogE[bandLogE_ptr + num * m.nbEBands + i] = -14336; } } while (++num < C); } } internal static class Rate { private static readonly byte[] LOG2_FRAC_TABLE = new byte[24] { 0, 8, 13, 16, 19, 21, 23, 24, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37 }; private const int ALLOC_STEPS = 6; internal static int get_pulses(int i) { if (i >= 8) { return 8 + (i & 7) << (i >> 3) - 1; } return i; } internal static int bits2pulses(CeltMode m, int band, int LM, int bits) { LM++; byte[] bits2 = m.cache.bits; int num = m.cache.index[LM * m.nbEBands + band]; int num2 = 0; int num3 = bits2[num]; bits--; for (int i = 0; i < 6; i++) { int num4 = num2 + num3 + 1 >> 1; if (bits2[num + num4] >= bits) { num3 = num4; } else { num2 = num4; } } if (bits - ((num2 == 0) ? (-1) : bits2[num + num2]) <= bits2[num + num3] - bits) { return num2; } return num3; } internal static int pulses2bits(CeltMode m, int band, int LM, int pulses) { LM++; if (pulses != 0) { return m.cache.bits[m.cache.index[LM * m.nbEBands + band] + pulses] + 1; } return 0; } internal static int interp_bits2pulses_encode(CeltMode m, int start, int end, int skip_start, int[] bits1, int[] bits2, int[] thresh, int[] cap, int total, out int _balance, int skip_rsv, ref int intensity, int intensity_rsv, ref int dual_stereo, int dual_stereo_rsv, int[] bits, int[] ebits, int[] fine_priority, int C, int LM, EntropyCoder ec, Span encodedData, int prev, int signalBandwidth) { int num = -1; int num2 = C << 3; int num3 = ((C > 1) ? 1 : 0); int num4 = LM << 3; int num5 = 0; int num6 = 64; int num9; int num8; int num10; for (int i = 0; i < 6; i++) { int num7 = num5 + num6 >> 1; num8 = 0; num9 = 0; num10 = end; while (num10-- > start) { int num11 = bits1[num10] + (num7 * bits2[num10] >> 6); if (num11 >= thresh[num10] || num9 != 0) { num9 = 1; num8 += Inlines.IMIN(num11, cap[num10]); } else if (num11 >= num2) { num8 += num2; } } if (num8 > total) { num6 = num7; } else { num5 = num7; } } num8 = 0; num9 = 0; num10 = end; while (num10-- > start) { int num12 = bits1[num10] + (num5 * bits2[num10] >> 6); if (num12 < thresh[num10] && num9 == 0) { num12 = ((num12 >= num2) ? num2 : 0); } else { num9 = 1; } num8 += (bits[num10] = Inlines.IMIN(num12, cap[num10])); } num = end; int num14; int num13; while (true) { num10 = num - 1; if (num10 <= skip_start) { total += skip_rsv; break; } num13 = total - num8; num14 = Inlines.celt_udiv(num13, m.eBands[num] - m.eBands[start]); num13 -= (m.eBands[num] - m.eBands[start]) * num14; int num15 = Inlines.IMAX(num13 - (m.eBands[num10] - m.eBands[start]), 0); int num16 = m.eBands[num] - m.eBands[num10]; int num17 = bits[num10] + num14 * num16 + num15; if (num17 >= Inlines.IMAX(thresh[num10], num2 + 8)) { if (num <= start + 2 || (num17 > ((num10 < prev) ? 7 : 9) * num16 << LM << 3 >> 4 && num10 <= signalBandwidth)) { ec.enc_bit_logp(encodedData, 1, 1u); break; } ec.enc_bit_logp(encodedData, 0, 1u); num8 += 8; num17 -= 8; } num8 -= bits[num10] + intensity_rsv; if (intensity_rsv > 0) { intensity_rsv = LOG2_FRAC_TABLE[num10 - start]; } num8 += intensity_rsv; if (num17 >= num2) { num8 += num2; bits[num10] = num2; } else { bits[num10] = 0; } num--; } if (intensity_rsv > 0) { intensity = Inlines.IMIN(intensity, num); ec.enc_uint(encodedData, (uint)(intensity - start), (uint)(num + 1 - start)); } else { intensity = 0; } if (intensity <= start) { total += dual_stereo_rsv; dual_stereo_rsv = 0; } if (dual_stereo_rsv > 0) { ec.enc_bit_logp(encodedData, dual_stereo, 1u); } else { dual_stereo = 0; } num13 = total - num8; num14 = Inlines.celt_udiv(num13, m.eBands[num] - m.eBands[start]); num13 -= (m.eBands[num] - m.eBands[start]) * num14; for (num10 = start; num10 < num; num10++) { bits[num10] += num14 * (m.eBands[num10 + 1] - m.eBands[num10]); } for (num10 = start; num10 < num; num10++) { int num18 = Inlines.IMIN(num13, m.eBands[num10 + 1] - m.eBands[num10]); bits[num10] += num18; num13 -= num18; } int num19 = 0; for (num10 = start; num10 < num; num10++) { int num20 = m.eBands[num10 + 1] - m.eBands[num10] << LM; int num21 = bits[num10] + num19; int num22; if (num20 > 1) { num22 = Inlines.MAX32(num21 - cap[num10], 0); bits[num10] = num21 - num22; int num23 = C * num20 + ((C == 2 && num20 > 2 && dual_stereo == 0 && num10 < intensity) ? 1 : 0); int num24 = num23 * (m.logN[num10] + num4); int num25 = (num24 >> 1) - num23 * 21; if (num20 == 2) { num25 += num23 << 3 >> 2; } if (bits[num10] + num25 < num23 * 2 << 3) { num25 += num24 >> 2; } else if (bits[num10] + num25 < num23 * 3 << 3) { num25 += num24 >> 3; } ebits[num10] = Inlines.IMAX(0, bits[num10] + num25 + (num23 << 2)); ebits[num10] = Inlines.celt_udiv(ebits[num10], num23) >> 3; if (C * ebits[num10] > bits[num10] >> 3) { ebits[num10] = bits[num10] >> num3 >> 3; } ebits[num10] = Inlines.IMIN(ebits[num10], 8); fine_priority[num10] = ((ebits[num10] * (num23 << 3) >= bits[num10] + num25) ? 1 : 0); bits[num10] -= C * ebits[num10] << 3; } else { num22 = Inlines.MAX32(0, num21 - (C << 3)); bits[num10] = num21 - num22; ebits[num10] = 0; fine_priority[num10] = 1; } if (num22 > 0) { int num26 = Inlines.IMIN(num22 >> num3 + 3, 8 - ebits[num10]); ebits[num10] += num26; int num27 = num26 * C << 3; fine_priority[num10] = ((num27 >= num22 - num19) ? 1 : 0); num22 -= num27; } num19 = num22; } _balance = num19; for (; num10 < end; num10++) { ebits[num10] = bits[num10] >> num3 >> 3; bits[num10] = 0; fine_priority[num10] = ((ebits[num10] < 1) ? 1 : 0); } return num; } internal static int interp_bits2pulses_decode(CeltMode m, int start, int end, int skip_start, int[] bits1, int[] bits2, int[] thresh, int[] cap, int total, out int _balance, int skip_rsv, ref int intensity, int intensity_rsv, ref int dual_stereo, int dual_stereo_rsv, int[] bits, int[] ebits, int[] fine_priority, int C, int LM, EntropyCoder ec, ReadOnlySpan encodedData, int prev, int signalBandwidth) { int num = -1; int num2 = C << 3; int num3 = ((C > 1) ? 1 : 0); int num4 = LM << 3; int num5 = 0; int num6 = 64; int num9; int num8; int num10; for (int i = 0; i < 6; i++) { int num7 = num5 + num6 >> 1; num8 = 0; num9 = 0; num10 = end; while (num10-- > start) { int num11 = bits1[num10] + (num7 * bits2[num10] >> 6); if (num11 >= thresh[num10] || num9 != 0) { num9 = 1; num8 += Inlines.IMIN(num11, cap[num10]); } else if (num11 >= num2) { num8 += num2; } } if (num8 > total) { num6 = num7; } else { num5 = num7; } } num8 = 0; num9 = 0; num10 = end; while (num10-- > start) { int num12 = bits1[num10] + (num5 * bits2[num10] >> 6); if (num12 < thresh[num10] && num9 == 0) { num12 = ((num12 >= num2) ? num2 : 0); } else { num9 = 1; } num8 += (bits[num10] = Inlines.IMIN(num12, cap[num10])); } num = end; int num14; int num13; while (true) { num10 = num - 1; if (num10 <= skip_start) { total += skip_rsv; break; } num13 = total - num8; num14 = Inlines.celt_udiv(num13, m.eBands[num] - m.eBands[start]); num13 -= (m.eBands[num] - m.eBands[start]) * num14; int num15 = Inlines.IMAX(num13 - (m.eBands[num10] - m.eBands[start]), 0); int num16 = m.eBands[num] - m.eBands[num10]; int num17 = bits[num10] + num14 * num16 + num15; if (num17 >= Inlines.IMAX(thresh[num10], num2 + 8)) { if (ec.dec_bit_logp(encodedData, 1u) != 0) { break; } num8 += 8; num17 -= 8; } num8 -= bits[num10] + intensity_rsv; if (intensity_rsv > 0) { intensity_rsv = LOG2_FRAC_TABLE[num10 - start]; } num8 += intensity_rsv; if (num17 >= num2) { num8 += num2; bits[num10] = num2; } else { bits[num10] = 0; } num--; } if (intensity_rsv > 0) { intensity = start + (int)ec.dec_uint(encodedData, (uint)(num + 1 - start)); } else { intensity = 0; } if (intensity <= start) { total += dual_stereo_rsv; dual_stereo_rsv = 0; } if (dual_stereo_rsv > 0) { dual_stereo = ec.dec_bit_logp(encodedData, 1u); } else { dual_stereo = 0; } num13 = total - num8; num14 = Inlines.celt_udiv(num13, m.eBands[num] - m.eBands[start]); num13 -= (m.eBands[num] - m.eBands[start]) * num14; for (num10 = start; num10 < num; num10++) { bits[num10] += num14 * (m.eBands[num10 + 1] - m.eBands[num10]); } for (num10 = start; num10 < num; num10++) { int num18 = Inlines.IMIN(num13, m.eBands[num10 + 1] - m.eBands[num10]); bits[num10] += num18; num13 -= num18; } int num19 = 0; for (num10 = start; num10 < num; num10++) { int num20 = m.eBands[num10 + 1] - m.eBands[num10] << LM; int num21 = bits[num10] + num19; int num22; if (num20 > 1) { num22 = Inlines.MAX32(num21 - cap[num10], 0); bits[num10] = num21 - num22; int num23 = C * num20 + ((C == 2 && num20 > 2 && dual_stereo == 0 && num10 < intensity) ? 1 : 0); int num24 = num23 * (m.logN[num10] + num4); int num25 = (num24 >> 1) - num23 * 21; if (num20 == 2) { num25 += num23 << 3 >> 2; } if (bits[num10] + num25 < num23 * 2 << 3) { num25 += num24 >> 2; } else if (bits[num10] + num25 < num23 * 3 << 3) { num25 += num24 >> 3; } ebits[num10] = Inlines.IMAX(0, bits[num10] + num25 + (num23 << 2)); ebits[num10] = Inlines.celt_udiv(ebits[num10], num23) >> 3; if (C * ebits[num10] > bits[num10] >> 3) { ebits[num10] = bits[num10] >> num3 >> 3; } ebits[num10] = Inlines.IMIN(ebits[num10], 8); fine_priority[num10] = ((ebits[num10] * (num23 << 3) >= bits[num10] + num25) ? 1 : 0); bits[num10] -= C * ebits[num10] << 3; } else { num22 = Inlines.MAX32(0, num21 - (C << 3)); bits[num10] = num21 - num22; ebits[num10] = 0; fine_priority[num10] = 1; } if (num22 > 0) { int num26 = Inlines.IMIN(num22 >> num3 + 3, 8 - ebits[num10]); ebits[num10] += num26; int num27 = num26 * C << 3; fine_priority[num10] = ((num27 >= num22 - num19) ? 1 : 0); num22 -= num27; } num19 = num22; } _balance = num19; for (; num10 < end; num10++) { ebits[num10] = bits[num10] >> num3 >> 3; bits[num10] = 0; fine_priority[num10] = ((ebits[num10] < 1) ? 1 : 0); } return num; } internal static int compute_allocation_encode(CeltMode m, int start, int end, int[] offsets, int[] cap, int alloc_trim, ref int intensity, ref int dual_stereo, int total, out int balance, int[] pulses, int[] ebits, int[] fine_priority, int C, int LM, EntropyCoder ec, Span encodedData, int prev, int signalBandwidth) { total = Inlines.IMAX(total, 0); int nbEBands = m.nbEBands; int skip_start = start; int num = ((total >= 8) ? 8 : 0); total -= num; int num3; int num2 = (num3 = 0); if (C == 2) { num2 = LOG2_FRAC_TABLE[end - start]; if (num2 > total) { num2 = 0; } else { total -= num2; num3 = ((total >= 8) ? 8 : 0); total -= num3; } } int[] array = new int[nbEBands]; int[] array2 = new int[nbEBands]; int[] array3 = new int[nbEBands]; int[] array4 = new int[nbEBands]; for (int i = start; i < end; i++) { array3[i] = Inlines.IMAX(C << 3, 3 * (m.eBands[i + 1] - m.eBands[i]) << LM << 3 >> 4); array4[i] = C * (m.eBands[i + 1] - m.eBands[i]) * (alloc_trim - 5 - LM) * (end - i - 1) * (1 << LM + 3) >> 6; if (m.eBands[i + 1] - m.eBands[i] << LM == 1) { array4[i] -= C << 3; } } int num4 = 1; int num5 = m.nbAllocVectors - 1; do { int num6 = 0; int num7 = 0; int num8 = num4 + num5 >> 1; int i = end; while (i-- > start) { int num9 = m.eBands[i + 1] - m.eBands[i]; int num10 = C * num9 * m.allocVectors[num8 * nbEBands + i] << LM >> 2; if (num10 > 0) { num10 = Inlines.IMAX(0, num10 + array4[i]); } num10 += offsets[i]; if (num10 >= array3[i] || num6 != 0) { num6 = 1; num7 += Inlines.IMIN(num10, cap[i]); } else if (num10 >= C << 3) { num7 += C << 3; } } if (num7 > total) { num5 = num8 - 1; } else { num4 = num8 + 1; } } while (num4 <= num5); num5 = num4--; for (int i = start; i < end; i++) { int num11 = m.eBands[i + 1] - m.eBands[i]; int num12 = C * num11 * m.allocVectors[num4 * nbEBands + i] << LM >> 2; int num13 = ((num5 >= m.nbAllocVectors) ? cap[i] : (C * num11 * m.allocVectors[num5 * nbEBands + i] << LM >> 2)); if (num12 > 0) { num12 = Inlines.IMAX(0, num12 + array4[i]); } if (num13 > 0) { num13 = Inlines.IMAX(0, num13 + array4[i]); } if (num4 > 0) { num12 += offsets[i]; } num13 += offsets[i]; if (offsets[i] > 0) { skip_start = i; } num13 = Inlines.IMAX(0, num13 - num12); array[i] = num12; array2[i] = num13; } return interp_bits2pulses_encode(m, start, end, skip_start, array, array2, array3, cap, total, out balance, num, ref intensity, num2, ref dual_stereo, num3, pulses, ebits, fine_priority, C, LM, ec, encodedData, prev, signalBandwidth); } internal static int compute_allocation_decode(CeltMode m, int start, int end, int[] offsets, int[] cap, int alloc_trim, ref int intensity, ref int dual_stereo, int total, out int balance, int[] pulses, int[] ebits, int[] fine_priority, int C, int LM, EntropyCoder ec, ReadOnlySpan encodedData, int prev, int signalBandwidth) { total = Inlines.IMAX(total, 0); int nbEBands = m.nbEBands; int skip_start = start; int num = ((total >= 8) ? 8 : 0); total -= num; int num3; int num2 = (num3 = 0); if (C == 2) { num2 = LOG2_FRAC_TABLE[end - start]; if (num2 > total) { num2 = 0; } else { total -= num2; num3 = ((total >= 8) ? 8 : 0); total -= num3; } } int[] array = new int[nbEBands]; int[] array2 = new int[nbEBands]; int[] array3 = new int[nbEBands]; int[] array4 = new int[nbEBands]; for (int i = start; i < end; i++) { array3[i] = Inlines.IMAX(C << 3, 3 * (m.eBands[i + 1] - m.eBands[i]) << LM << 3 >> 4); array4[i] = C * (m.eBands[i + 1] - m.eBands[i]) * (alloc_trim - 5 - LM) * (end - i - 1) * (1 << LM + 3) >> 6; if (m.eBands[i + 1] - m.eBands[i] << LM == 1) { array4[i] -= C << 3; } } int num4 = 1; int num5 = m.nbAllocVectors - 1; do { int num6 = 0; int num7 = 0; int num8 = num4 + num5 >> 1; int i = end; while (i-- > start) { int num9 = m.eBands[i + 1] - m.eBands[i]; int num10 = C * num9 * m.allocVectors[num8 * nbEBands + i] << LM >> 2; if (num10 > 0) { num10 = Inlines.IMAX(0, num10 + array4[i]); } num10 += offsets[i]; if (num10 >= array3[i] || num6 != 0) { num6 = 1; num7 += Inlines.IMIN(num10, cap[i]); } else if (num10 >= C << 3) { num7 += C << 3; } } if (num7 > total) { num5 = num8 - 1; } else { num4 = num8 + 1; } } while (num4 <= num5); num5 = num4--; for (int i = start; i < end; i++) { int num11 = m.eBands[i + 1] - m.eBands[i]; int num12 = C * num11 * m.allocVectors[num4 * nbEBands + i] << LM >> 2; int num13 = ((num5 >= m.nbAllocVectors) ? cap[i] : (C * num11 * m.allocVectors[num5 * nbEBands + i] << LM >> 2)); if (num12 > 0) { num12 = Inlines.IMAX(0, num12 + array4[i]); } if (num13 > 0) { num13 = Inlines.IMAX(0, num13 + array4[i]); } if (num4 > 0) { num12 += offsets[i]; } num13 += offsets[i]; if (offsets[i] > 0) { skip_start = i; } num13 = Inlines.IMAX(0, num13 - num12); array[i] = num12; array2[i] = num13; } return interp_bits2pulses_decode(m, start, end, skip_start, array, array2, array3, cap, total, out balance, num, ref intensity, num2, ref dual_stereo, num3, pulses, ebits, fine_priority, C, LM, ec, encodedData, prev, signalBandwidth); } } internal static class Tables { internal static readonly byte[] eMeans = new byte[25] { 103, 100, 92, 85, 81, 77, 72, 70, 78, 75, 73, 71, 78, 74, 69, 72, 70, 74, 76, 71, 60, 60, 60, 60, 60 }; internal static readonly int[] ordery_table = new int[30] { 1, 0, 3, 0, 2, 1, 7, 0, 4, 3, 6, 1, 5, 2, 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5 }; internal static readonly short[] eband5ms = new short[22] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 }; internal static readonly byte[][][] e_prob_model = new byte[4][][] { new byte[2][] { new byte[42] { 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40, 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11 }, new byte[42] { 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66, 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50 } }, new byte[2][] { new byte[42] { 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18, 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9 }, new byte[42] { 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60, 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45 } }, new byte[2][] { new byte[42] { 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16, 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10 }, new byte[42] { 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55, 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42 } }, new byte[2][] { new byte[42] { 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25, 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15 }, new byte[42] { 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52, 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40 } } }; internal static readonly sbyte[][] tf_select_table = new sbyte[4][] { new sbyte[8] { 0, -1, 0, -1, 0, -1, 0, -1 }, new sbyte[8] { 0, -1, 0, -2, 1, 0, 1, -1 }, new sbyte[8] { 0, -2, 0, -3, 2, 0, 1, -1 }, new sbyte[8] { 0, -2, 0, -3, 3, 0, 1, -1 } }; internal static readonly byte[] trim_icdf = new byte[11] { 126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0 }; internal static readonly byte[] spread_icdf = new byte[4] { 25, 23, 2, 0 }; internal static readonly byte[] tapset_icdf = new byte[3] { 2, 1, 0 }; internal static readonly byte[] band_allocation = new byte[231] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, 110, 100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0, 118, 110, 103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0, 126, 119, 112, 104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0, 134, 127, 120, 114, 103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1, 144, 137, 130, 124, 113, 107, 101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1, 152, 145, 138, 132, 123, 117, 111, 105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, 162, 155, 148, 142, 133, 127, 121, 115, 108, 102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, 172, 165, 158, 152, 143, 137, 131, 125, 118, 112, 106, 100, 94, 87, 81, 75, 69, 63, 56, 45, 20, 200, 200, 200, 200, 200, 200, 200, 200, 198, 193, 188, 183, 178, 173, 168, 163, 158, 153, 148, 129, 104 }; internal static readonly uint[] CELT_PVQ_U_DATA = new uint[1272] { 1u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 3u, 5u, 7u, 9u, 11u, 13u, 15u, 17u, 19u, 21u, 23u, 25u, 27u, 29u, 31u, 33u, 35u, 37u, 39u, 41u, 43u, 45u, 47u, 49u, 51u, 53u, 55u, 57u, 59u, 61u, 63u, 65u, 67u, 69u, 71u, 73u, 75u, 77u, 79u, 81u, 83u, 85u, 87u, 89u, 91u, 93u, 95u, 97u, 99u, 101u, 103u, 105u, 107u, 109u, 111u, 113u, 115u, 117u, 119u, 121u, 123u, 125u, 127u, 129u, 131u, 133u, 135u, 137u, 139u, 141u, 143u, 145u, 147u, 149u, 151u, 153u, 155u, 157u, 159u, 161u, 163u, 165u, 167u, 169u, 171u, 173u, 175u, 177u, 179u, 181u, 183u, 185u, 187u, 189u, 191u, 193u, 195u, 197u, 199u, 201u, 203u, 205u, 207u, 209u, 211u, 213u, 215u, 217u, 219u, 221u, 223u, 225u, 227u, 229u, 231u, 233u, 235u, 237u, 239u, 241u, 243u, 245u, 247u, 249u, 251u, 253u, 255u, 257u, 259u, 261u, 263u, 265u, 267u, 269u, 271u, 273u, 275u, 277u, 279u, 281u, 283u, 285u, 287u, 289u, 291u, 293u, 295u, 297u, 299u, 301u, 303u, 305u, 307u, 309u, 311u, 313u, 315u, 317u, 319u, 321u, 323u, 325u, 327u, 329u, 331u, 333u, 335u, 337u, 339u, 341u, 343u, 345u, 347u, 349u, 351u, 13u, 25u, 41u, 61u, 85u, 113u, 145u, 181u, 221u, 265u, 313u, 365u, 421u, 481u, 545u, 613u, 685u, 761u, 841u, 925u, 1013u, 1105u, 1201u, 1301u, 1405u, 1513u, 1625u, 1741u, 1861u, 1985u, 2113u, 2245u, 2381u, 2521u, 2665u, 2813u, 2965u, 3121u, 3281u, 3445u, 3613u, 3785u, 3961u, 4141u, 4325u, 4513u, 4705u, 4901u, 5101u, 5305u, 5513u, 5725u, 5941u, 6161u, 6385u, 6613u, 6845u, 7081u, 7321u, 7565u, 7813u, 8065u, 8321u, 8581u, 8845u, 9113u, 9385u, 9661u, 9941u, 10225u, 10513u, 10805u, 11101u, 11401u, 11705u, 12013u, 12325u, 12641u, 12961u, 13285u, 13613u, 13945u, 14281u, 14621u, 14965u, 15313u, 15665u, 16021u, 16381u, 16745u, 17113u, 17485u, 17861u, 18241u, 18625u, 19013u, 19405u, 19801u, 20201u, 20605u, 21013u, 21425u, 21841u, 22261u, 22685u, 23113u, 23545u, 23981u, 24421u, 24865u, 25313u, 25765u, 26221u, 26681u, 27145u, 27613u, 28085u, 28561u, 29041u, 29525u, 30013u, 30505u, 31001u, 31501u, 32005u, 32513u, 33025u, 33541u, 34061u, 34585u, 35113u, 35645u, 36181u, 36721u, 37265u, 37813u, 38365u, 38921u, 39481u, 40045u, 40613u, 41185u, 41761u, 42341u, 42925u, 43513u, 44105u, 44701u, 45301u, 45905u, 46513u, 47125u, 47741u, 48361u, 48985u, 49613u, 50245u, 50881u, 51521u, 52165u, 52813u, 53465u, 54121u, 54781u, 55445u, 56113u, 56785u, 57461u, 58141u, 58825u, 59513u, 60205u, 60901u, 61601u, 63u, 129u, 231u, 377u, 575u, 833u, 1159u, 1561u, 2047u, 2625u, 3303u, 4089u, 4991u, 6017u, 7175u, 8473u, 9919u, 11521u, 13287u, 15225u, 17343u, 19649u, 22151u, 24857u, 27775u, 30913u, 34279u, 37881u, 41727u, 45825u, 50183u, 54809u, 59711u, 64897u, 70375u, 76153u, 82239u, 88641u, 95367u, 102425u, 109823u, 117569u, 125671u, 134137u, 142975u, 152193u, 161799u, 171801u, 182207u, 193025u, 204263u, 215929u, 228031u, 240577u, 253575u, 267033u, 280959u, 295361u, 310247u, 325625u, 341503u, 357889u, 374791u, 392217u, 410175u, 428673u, 447719u, 467321u, 487487u, 508225u, 529543u, 551449u, 573951u, 597057u, 620775u, 645113u, 670079u, 695681u, 721927u, 748825u, 776383u, 804609u, 833511u, 863097u, 893375u, 924353u, 956039u, 988441u, 1021567u, 1055425u, 1090023u, 1125369u, 1161471u, 1198337u, 1235975u, 1274393u, 1313599u, 1353601u, 1394407u, 1436025u, 1478463u, 1521729u, 1565831u, 1610777u, 1656575u, 1703233u, 1750759u, 1799161u, 1848447u, 1898625u, 1949703u, 2001689u, 2054591u, 2108417u, 2163175u, 2218873u, 2275519u, 2333121u, 2391687u, 2451225u, 2511743u, 2573249u, 2635751u, 2699257u, 2763775u, 2829313u, 2895879u, 2963481u, 3032127u, 3101825u, 3172583u, 3244409u, 3317311u, 3391297u, 3466375u, 3542553u, 3619839u, 3698241u, 3777767u, 3858425u, 3940223u, 4023169u, 4107271u, 4192537u, 4278975u, 4366593u, 4455399u, 4545401u, 4636607u, 4729025u, 4822663u, 4917529u, 5013631u, 5110977u, 5209575u, 5309433u, 5410559u, 5512961u, 5616647u, 5721625u, 5827903u, 5935489u, 6044391u, 6154617u, 6266175u, 6379073u, 6493319u, 6608921u, 6725887u, 6844225u, 6963943u, 7085049u, 7207551u, 321u, 681u, 1289u, 2241u, 3649u, 5641u, 8361u, 11969u, 16641u, 22569u, 29961u, 39041u, 50049u, 63241u, 78889u, 97281u, 118721u, 143529u, 172041u, 204609u, 241601u, 283401u, 330409u, 383041u, 441729u, 506921u, 579081u, 658689u, 746241u, 842249u, 947241u, 1061761u, 1186369u, 1321641u, 1468169u, 1626561u, 1797441u, 1981449u, 2179241u, 2391489u, 2618881u, 2862121u, 3121929u, 3399041u, 3694209u, 4008201u, 4341801u, 4695809u, 5071041u, 5468329u, 5888521u, 6332481u, 6801089u, 7295241u, 7815849u, 8363841u, 8940161u, 9545769u, 10181641u, 10848769u, 11548161u, 12280841u, 13047849u, 13850241u, 14689089u, 15565481u, 16480521u, 17435329u, 18431041u, 19468809u, 20549801u, 21675201u, 22846209u, 24064041u, 25329929u, 26645121u, 28010881u, 29428489u, 30899241u, 32424449u, 34005441u, 35643561u, 37340169u, 39096641u, 40914369u, 42794761u, 44739241u, 46749249u, 48826241u, 50971689u, 53187081u, 55473921u, 57833729u, 60268041u, 62778409u, 65366401u, 68033601u, 70781609u, 73612041u, 76526529u, 79526721u, 82614281u, 85790889u, 89058241u, 92418049u, 95872041u, 99421961u, 103069569u, 106816641u, 110664969u, 114616361u, 118672641u, 122835649u, 127107241u, 131489289u, 135983681u, 140592321u, 145317129u, 150160041u, 155123009u, 160208001u, 165417001u, 170752009u, 176215041u, 181808129u, 187533321u, 193392681u, 199388289u, 205522241u, 211796649u, 218213641u, 224775361u, 231483969u, 238341641u, 245350569u, 252512961u, 259831041u, 267307049u, 274943241u, 282741889u, 290705281u, 298835721u, 307135529u, 315607041u, 324252609u, 333074601u, 342075401u, 351257409u, 360623041u, 370174729u, 379914921u, 389846081u, 399970689u, 410291241u, 420810249u, 431530241u, 442453761u, 453583369u, 464921641u, 476471169u, 488234561u, 500214441u, 512413449u, 524834241u, 537479489u, 550351881u, 563454121u, 576788929u, 590359041u, 604167209u, 618216201u, 632508801u, 1683u, 3653u, 7183u, 13073u, 22363u, 36365u, 56695u, 85305u, 124515u, 177045u, 246047u, 335137u, 448427u, 590557u, 766727u, 982729u, 1244979u, 1560549u, 1937199u, 2383409u, 2908411u, 3522221u, 4235671u, 5060441u, 6009091u, 7095093u, 8332863u, 9737793u, 11326283u, 13115773u, 15124775u, 17372905u, 19880915u, 22670725u, 25765455u, 29189457u, 32968347u, 37129037u, 41699767u, 46710137u, 52191139u, 58175189u, 64696159u, 71789409u, 79491819u, 87841821u, 96879431u, 106646281u, 117185651u, 128542501u, 140763503u, 153897073u, 167993403u, 183104493u, 199284183u, 216588185u, 235074115u, 254801525u, 275831935u, 298228865u, 322057867u, 347386557u, 374284647u, 402823977u, 433078547u, 465124549u, 499040399u, 534906769u, 572806619u, 612825229u, 655050231u, 699571641u, 746481891u, 795875861u, 847850911u, 902506913u, 959946283u, 1020274013u, 1083597703u, 1150027593u, 1219676595u, 1292660325u, 1369097135u, 1449108145u, 1532817275u, 1620351277u, 1711839767u, 1807415257u, 1907213187u, 2011371957u, 2120032959u, 8989u, 19825u, 40081u, 75517u, 134245u, 227305u, 369305u, 579125u, 880685u, 1303777u, 1884961u, 2668525u, 3707509u, 5064793u, 6814249u, 9041957u, 11847485u, 15345233u, 19665841u, 24957661u, 31388293u, 39146185u, 48442297u, 59511829u, 72616013u, 88043969u, 106114625u, 127178701u, 151620757u, 179861305u, 212358985u, 249612805u, 292164445u, 340600625u, 395555537u, 457713341u, 527810725u, 606639529u, 695049433u, 793950709u, 904317037u, 1027188385u, 1163673953u, 1314955181u, 1482288821u, 1667010073u, 1870535785u, 2094367717u, 48639u, 108545u, 224143u, 433905u, 795455u, 1392065u, 2340495u, 3800305u, 5984767u, 9173505u, 13726991u, 20103025u, 28875327u, 40754369u, 56610575u, 77500017u, 104692735u, 139703809u, 184327311u, 240673265u, 311207743u, 398796225u, 506750351u, 638878193u, 799538175u, 993696769u, 1226990095u, 1505789553u, 1837271615u, 2229491905u, 265729u, 598417u, 1256465u, 2485825u, 4673345u, 8405905u, 14546705u, 24331777u, 39490049u, 62390545u, 96220561u, 145198913u, 214828609u, 312193553u, 446304145u, 628496897u, 872893441u, 1196924561u, 1621925137u, 2173806145u, 1462563u, 3317445u, 7059735u, 14218905u, 27298155u, 50250765u, 89129247u, 152951073u, 254831667u, 413442773u, 654862247u, 1014889769u, 1541911931u, 2300409629u, 3375210671u, 8097453u, 18474633u, 39753273u, 81270333u, 158819253u, 298199265u, 540279585u, 948062325u, 1616336765u, 45046719u, 103274625u, 224298231u, 464387817u, 921406335u, 1759885185u, 3248227095u, 251595969u, 579168825u, 1267854873u, 2653649025u, 1409933619u }; internal static readonly int[] window120 = new int[120] { 2, 20, 55, 108, 178, 266, 372, 494, 635, 792, 966, 1157, 1365, 1590, 1831, 2089, 2362, 2651, 2956, 3276, 3611, 3961, 4325, 4703, 5094, 5499, 5916, 6346, 6788, 7241, 7705, 8179, 8663, 9156, 9657, 10167, 10684, 11207, 11736, 12271, 12810, 13353, 13899, 14447, 14997, 15547, 16098, 16648, 17197, 17744, 18287, 18827, 19363, 19893, 20418, 20936, 21447, 21950, 22445, 22931, 23407, 23874, 24330, 24774, 25208, 25629, 26039, 26435, 26819, 27190, 27548, 27893, 28224, 28541, 28845, 29135, 29411, 29674, 29924, 30160, 30384, 30594, 30792, 30977, 31151, 31313, 31463, 31602, 31731, 31849, 31958, 32057, 32148, 32229, 32303, 32370, 32429, 32481, 32528, 32568, 32604, 32634, 32661, 32683, 32701, 32717, 32729, 32740, 32748, 32754, 32758, 32762, 32764, 32766, 32767, 32767, 32767, 32767, 32767, 32767 }; internal static readonly short[] logN400 = new short[21] { 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36 }; internal static readonly short[] cache_index50 = new short[105] { -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, 82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, 41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, 318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, 305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387 }; internal static readonly byte[] cache_bits50 = new byte[392] { 40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, 66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, 94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, 124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, 28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, 153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, 229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, 25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, 185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, 163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, 228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, 106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, 182, 234 }; internal static readonly byte[] cache_caps50 = new byte[168] { 224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, 178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, 240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, 160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, 138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, 204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, 185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, 207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, 188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, 204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, 140, 66, 40 }; internal static readonly short[] fft_twiddles48000_960 = new short[960] { 32767, 0, 32766, -429, 32757, -858, 32743, -1287, 32724, -1715, 32698, -2143, 32667, -2570, 32631, -2998, 32588, -3425, 32541, -3851, 32488, -4277, 32429, -4701, 32364, -5125, 32295, -5548, 32219, -5971, 32138, -6393, 32051, -6813, 31960, -7231, 31863, -7650, 31760, -8067, 31652, -8481, 31539, -8895, 31419, -9306, 31294, -9716, 31165, -10126, 31030, -10532, 30889, -10937, 30743, -11340, 30592, -11741, 30436, -12141, 30274, -12540, 30107, -12935, 29936, -13328, 29758, -13718, 29577, -14107, 29390, -14493, 29197, -14875, 29000, -15257, 28797, -15635, 28590, -16010, 28379, -16384, 28162, -16753, 27940, -17119, 27714, -17484, 27482, -17845, 27246, -18205, 27006, -18560, 26760, -18911, 26510, -19260, 26257, -19606, 25997, -19947, 25734, -20286, 25466, -20621, 25194, -20952, 24918, -21281, 24637, -21605, 24353, -21926, 24063, -22242, 23770, -22555, 23473, -22865, 23171, -23171, 22866, -23472, 22557, -23769, 22244, -24063, 21927, -24352, 21606, -24636, 21282, -24917, 20954, -25194, 20622, -25465, 20288, -25733, 19949, -25997, 19607, -26255, 19261, -26509, 18914, -26760, 18561, -27004, 18205, -27246, 17846, -27481, 17485, -27713, 17122, -27940, 16755, -28162, 16385, -28378, 16012, -28590, 15636, -28797, 15258, -28999, 14878, -29197, 14494, -29389, 14108, -29576, 13720, -29757, 13329, -29934, 12937, -30107, 12540, -30274, 12142, -30435, 11744, -30592, 11342, -30743, 10939, -30889, 10534, -31030, 10127, -31164, 9718, -31294, 9307, -31418, 8895, -31537, 8482, -31652, 8067, -31759, 7650, -31862, 7233, -31960, 6815, -32051, 6393, -32138, 5973, -32219, 5549, -32294, 5127, -32364, 4703, -32429, 4278, -32487, 3852, -32541, 3426, -32588, 2999, -32630, 2572, -32667, 2144, -32698, 1716, -32724, 1287, -32742, 860, -32757, 430, -32766, 0, -32767, -429, -32766, -858, -32757, -1287, -32743, -1715, -32724, -2143, -32698, -2570, -32667, -2998, -32631, -3425, -32588, -3851, -32541, -4277, -32488, -4701, -32429, -5125, -32364, -5548, -32295, -5971, -32219, -6393, -32138, -6813, -32051, -7231, -31960, -7650, -31863, -8067, -31760, -8481, -31652, -8895, -31539, -9306, -31419, -9716, -31294, -10126, -31165, -10532, -31030, -10937, -30889, -11340, -30743, -11741, -30592, -12141, -30436, -12540, -30274, -12935, -30107, -13328, -29936, -13718, -29758, -14107, -29577, -14493, -29390, -14875, -29197, -15257, -29000, -15635, -28797, -16010, -28590, -16384, -28379, -16753, -28162, -17119, -27940, -17484, -27714, -17845, -27482, -18205, -27246, -18560, -27006, -18911, -26760, -19260, -26510, -19606, -26257, -19947, -25997, -20286, -25734, -20621, -25466, -20952, -25194, -21281, -24918, -21605, -24637, -21926, -24353, -22242, -24063, -22555, -23770, -22865, -23473, -23171, -23171, -23472, -22866, -23769, -22557, -24063, -22244, -24352, -21927, -24636, -21606, -24917, -21282, -25194, -20954, -25465, -20622, -25733, -20288, -25997, -19949, -26255, -19607, -26509, -19261, -26760, -18914, -27004, -18561, -27246, -18205, -27481, -17846, -27713, -17485, -27940, -17122, -28162, -16755, -28378, -16385, -28590, -16012, -28797, -15636, -28999, -15258, -29197, -14878, -29389, -14494, -29576, -14108, -29757, -13720, -29934, -13329, -30107, -12937, -30274, -12540, -30435, -12142, -30592, -11744, -30743, -11342, -30889, -10939, -31030, -10534, -31164, -10127, -31294, -9718, -31418, -9307, -31537, -8895, -31652, -8482, -31759, -8067, -31862, -7650, -31960, -7233, -32051, -6815, -32138, -6393, -32219, -5973, -32294, -5549, -32364, -5127, -32429, -4703, -32487, -4278, -32541, -3852, -32588, -3426, -32630, -2999, -32667, -2572, -32698, -2144, -32724, -1716, -32742, -1287, -32757, -860, -32766, -430, -32767, 0, -32766, 429, -32757, 858, -32743, 1287, -32724, 1715, -32698, 2143, -32667, 2570, -32631, 2998, -32588, 3425, -32541, 3851, -32488, 4277, -32429, 4701, -32364, 5125, -32295, 5548, -32219, 5971, -32138, 6393, -32051, 6813, -31960, 7231, -31863, 7650, -31760, 8067, -31652, 8481, -31539, 8895, -31419, 9306, -31294, 9716, -31165, 10126, -31030, 10532, -30889, 10937, -30743, 11340, -30592, 11741, -30436, 12141, -30274, 12540, -30107, 12935, -29936, 13328, -29758, 13718, -29577, 14107, -29390, 14493, -29197, 14875, -29000, 15257, -28797, 15635, -28590, 16010, -28379, 16384, -28162, 16753, -27940, 17119, -27714, 17484, -27482, 17845, -27246, 18205, -27006, 18560, -26760, 18911, -26510, 19260, -26257, 19606, -25997, 19947, -25734, 20286, -25466, 20621, -25194, 20952, -24918, 21281, -24637, 21605, -24353, 21926, -24063, 22242, -23770, 22555, -23473, 22865, -23171, 23171, -22866, 23472, -22557, 23769, -22244, 24063, -21927, 24352, -21606, 24636, -21282, 24917, -20954, 25194, -20622, 25465, -20288, 25733, -19949, 25997, -19607, 26255, -19261, 26509, -18914, 26760, -18561, 27004, -18205, 27246, -17846, 27481, -17485, 27713, -17122, 27940, -16755, 28162, -16385, 28378, -16012, 28590, -15636, 28797, -15258, 28999, -14878, 29197, -14494, 29389, -14108, 29576, -13720, 29757, -13329, 29934, -12937, 30107, -12540, 30274, -12142, 30435, -11744, 30592, -11342, 30743, -10939, 30889, -10534, 31030, -10127, 31164, -9718, 31294, -9307, 31418, -8895, 31537, -8482, 31652, -8067, 31759, -7650, 31862, -7233, 31960, -6815, 32051, -6393, 32138, -5973, 32219, -5549, 32294, -5127, 32364, -4703, 32429, -4278, 32487, -3852, 32541, -3426, 32588, -2999, 32630, -2572, 32667, -2144, 32698, -1716, 32724, -1287, 32742, -860, 32757, -430, 32766, 0, 32767, 429, 32766, 858, 32757, 1287, 32743, 1715, 32724, 2143, 32698, 2570, 32667, 2998, 32631, 3425, 32588, 3851, 32541, 4277, 32488, 4701, 32429, 5125, 32364, 5548, 32295, 5971, 32219, 6393, 32138, 6813, 32051, 7231, 31960, 7650, 31863, 8067, 31760, 8481, 31652, 8895, 31539, 9306, 31419, 9716, 31294, 10126, 31165, 10532, 31030, 10937, 30889, 11340, 30743, 11741, 30592, 12141, 30436, 12540, 30274, 12935, 30107, 13328, 29936, 13718, 29758, 14107, 29577, 14493, 29390, 14875, 29197, 15257, 29000, 15635, 28797, 16010, 28590, 16384, 28379, 16753, 28162, 17119, 27940, 17484, 27714, 17845, 27482, 18205, 27246, 18560, 27006, 18911, 26760, 19260, 26510, 19606, 26257, 19947, 25997, 20286, 25734, 20621, 25466, 20952, 25194, 21281, 24918, 21605, 24637, 21926, 24353, 22242, 24063, 22555, 23770, 22865, 23473, 23171, 23171, 23472, 22866, 23769, 22557, 24063, 22244, 24352, 21927, 24636, 21606, 24917, 21282, 25194, 20954, 25465, 20622, 25733, 20288, 25997, 19949, 26255, 19607, 26509, 19261, 26760, 18914, 27004, 18561, 27246, 18205, 27481, 17846, 27713, 17485, 27940, 17122, 28162, 16755, 28378, 16385, 28590, 16012, 28797, 15636, 28999, 15258, 29197, 14878, 29389, 14494, 29576, 14108, 29757, 13720, 29934, 13329, 30107, 12937, 30274, 12540, 30435, 12142, 30592, 11744, 30743, 11342, 30889, 10939, 31030, 10534, 31164, 10127, 31294, 9718, 31418, 9307, 31537, 8895, 31652, 8482, 31759, 8067, 31862, 7650, 31960, 7233, 32051, 6815, 32138, 6393, 32219, 5973, 32294, 5549, 32364, 5127, 32429, 4703, 32487, 4278, 32541, 3852, 32588, 3426, 32630, 2999, 32667, 2572, 32698, 2144, 32724, 1716, 32742, 1287, 32757, 860, 32766, 430 }; internal static readonly short[] fft_bitrev480 = new short[480] { 0, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448, 8, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456, 16, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464, 24, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472, 4, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452, 12, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460, 20, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468, 28, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476, 1, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449, 9, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457, 17, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465, 25, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473, 5, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453, 13, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461, 21, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469, 29, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477, 2, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450, 10, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458, 18, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466, 26, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474, 6, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454, 14, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462, 22, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470, 30, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478, 3, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451, 11, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459, 19, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467, 27, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475, 7, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455, 15, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463, 23, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471, 31, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479 }; internal static readonly short[] fft_bitrev240 = new short[240] { 0, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224, 4, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228, 8, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232, 12, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236, 1, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225, 5, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229, 9, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233, 13, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237, 2, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226, 6, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230, 10, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234, 14, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238, 3, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227, 7, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231, 11, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235, 15, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239 }; internal static readonly short[] fft_bitrev120 = new short[120] { 0, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112, 4, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116, 1, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113, 5, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117, 2, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114, 6, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118, 3, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115, 7, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119 }; internal static readonly short[] fft_bitrev60 = new short[60] { 0, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56, 1, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57, 2, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58, 3, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59 }; internal static readonly FFTState fft_state48000_960_0 = new FFTState { nfft = 480, scale = 17476, scale_shift = 8, shift = -1, factors = new short[16] { 5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0 }, bitrev = fft_bitrev480, twiddles = fft_twiddles48000_960 }; internal static readonly FFTState fft_state48000_960_1 = new FFTState { nfft = 240, scale = 17476, scale_shift = 7, shift = 1, factors = new short[16] { 5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, bitrev = fft_bitrev240, twiddles = fft_twiddles48000_960 }; internal static readonly FFTState fft_state48000_960_2 = new FFTState { nfft = 120, scale = 17476, scale_shift = 6, shift = 2, factors = new short[16] { 5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, bitrev = fft_bitrev120, twiddles = fft_twiddles48000_960 }; internal static readonly FFTState fft_state48000_960_3 = new FFTState { nfft = 60, scale = 17476, scale_shift = 5, shift = 3, factors = new short[16] { 5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, bitrev = fft_bitrev60, twiddles = fft_twiddles48000_960 }; internal static readonly short[] mdct_twiddles960 = new short[1800] { 32767, 32767, 32767, 32766, 32765, 32763, 32761, 32759, 32756, 32753, 32750, 32746, 32742, 32738, 32733, 32728, 32722, 32717, 32710, 32704, 32697, 32690, 32682, 32674, 32666, 32657, 32648, 32639, 32629, 32619, 32609, 32598, 32587, 32576, 32564, 32552, 32539, 32526, 32513, 32500, 32486, 32472, 32457, 32442, 32427, 32411, 32395, 32379, 32362, 32345, 32328, 32310, 32292, 32274, 32255, 32236, 32217, 32197, 32177, 32157, 32136, 32115, 32093, 32071, 32049, 32027, 32004, 31981, 31957, 31933, 31909, 31884, 31859, 31834, 31809, 31783, 31756, 31730, 31703, 31676, 31648, 31620, 31592, 31563, 31534, 31505, 31475, 31445, 31415, 31384, 31353, 31322, 31290, 31258, 31226, 31193, 31160, 31127, 31093, 31059, 31025, 30990, 30955, 30920, 30884, 30848, 30812, 30775, 30738, 30701, 30663, 30625, 30587, 30548, 30509, 30470, 30430, 30390, 30350, 30309, 30269, 30227, 30186, 30144, 30102, 30059, 30016, 29973, 29930, 29886, 29842, 29797, 29752, 29707, 29662, 29616, 29570, 29524, 29477, 29430, 29383, 29335, 29287, 29239, 29190, 29142, 29092, 29043, 28993, 28943, 28892, 28842, 28791, 28739, 28688, 28636, 28583, 28531, 28478, 28425, 28371, 28317, 28263, 28209, 28154, 28099, 28044, 27988, 27932, 27876, 27820, 27763, 27706, 27648, 27591, 27533, 27474, 27416, 27357, 27298, 27238, 27178, 27118, 27058, 26997, 26936, 26875, 26814, 26752, 26690, 26628, 26565, 26502, 26439, 26375, 26312, 26247, 26183, 26119, 26054, 25988, 25923, 25857, 25791, 25725, 25658, 25592, 25524, 25457, 25389, 25322, 25253, 25185, 25116, 25047, 24978, 24908, 24838, 24768, 24698, 24627, 24557, 24485, 24414, 24342, 24270, 24198, 24126, 24053, 23980, 23907, 23834, 23760, 23686, 23612, 23537, 23462, 23387, 23312, 23237, 23161, 23085, 23009, 22932, 22856, 22779, 22701, 22624, 22546, 22468, 22390, 22312, 22233, 22154, 22075, 21996, 21916, 21836, 21756, 21676, 21595, 21515, 21434, 21352, 21271, 21189, 21107, 21025, 20943, 20860, 20777, 20694, 20611, 20528, 20444, 20360, 20276, 20192, 20107, 20022, 19937, 19852, 19767, 19681, 19595, 19509, 19423, 19336, 19250, 19163, 19076, 18988, 18901, 18813, 18725, 18637, 18549, 18460, 18372, 18283, 18194, 18104, 18015, 17925, 17835, 17745, 17655, 17565, 17474, 17383, 17292, 17201, 17110, 17018, 16927, 16835, 16743, 16650, 16558, 16465, 16372, 16279, 16186, 16093, 15999, 15906, 15812, 15718, 15624, 15529, 15435, 15340, 15245, 15150, 15055, 14960, 14864, 14769, 14673, 14577, 14481, 14385, 14288, 14192, 14095, 13998, 13901, 13804, 13706, 13609, 13511, 13414, 13316, 13218, 13119, 13021, 12923, 12824, 12725, 12626, 12527, 12428, 12329, 12230, 12130, 12030, 11930, 11831, 11730, 11630, 11530, 11430, 11329, 11228, 11128, 11027, 10926, 10824, 10723, 10622, 10520, 10419, 10317, 10215, 10113, 10011, 9909, 9807, 9704, 9602, 9499, 9397, 9294, 9191, 9088, 8985, 8882, 8778, 8675, 8572, 8468, 8364, 8261, 8157, 8053, 7949, 7845, 7741, 7637, 7532, 7428, 7323, 7219, 7114, 7009, 6905, 6800, 6695, 6590, 6485, 6380, 6274, 6169, 6064, 5958, 5853, 5747, 5642, 5536, 5430, 5325, 5219, 5113, 5007, 4901, 4795, 4689, 4583, 4476, 4370, 4264, 4157, 4051, 3945, 3838, 3732, 3625, 3518, 3412, 3305, 3198, 3092, 2985, 2878, 2771, 2664, 2558, 2451, 2344, 2237, 2130, 2023, 1916, 1809, 1702, 1594, 1487, 1380, 1273, 1166, 1059, 952, 844, 737, 630, 523, 416, 308, 201, 94, -13, -121, -228, -335, -442, -550, -657, -764, -871, -978, -1086, -1193, -1300, -1407, -1514, -1621, -1728, -1835, -1942, -2049, -2157, -2263, -2370, -2477, -2584, -2691, -2798, -2905, -3012, -3118, -3225, -3332, -3439, -3545, -3652, -3758, -3865, -3971, -4078, -4184, -4290, -4397, -4503, -4609, -4715, -4821, -4927, -5033, -5139, -5245, -5351, -5457, -5562, -5668, -5774, -5879, -5985, -6090, -6195, -6301, -6406, -6511, -6616, -6721, -6826, -6931, -7036, -7140, -7245, -7349, -7454, -7558, -7663, -7767, -7871, -7975, -8079, -8183, -8287, -8390, -8494, -8597, -8701, -8804, -8907, -9011, -9114, -9217, -9319, -9422, -9525, -9627, -9730, -9832, -9934, -10037, -10139, -10241, -10342, -10444, -10546, -10647, -10748, -10850, -10951, -11052, -11153, -11253, -11354, -11455, -11555, -11655, -11756, -11856, -11955, -12055, -12155, -12254, -12354, -12453, -12552, -12651, -12750, -12849, -12947, -13046, -13144, -13242, -13340, -13438, -13536, -13633, -13731, -13828, -13925, -14022, -14119, -14216, -14312, -14409, -14505, -14601, -14697, -14793, -14888, -14984, -15079, -15174, -15269, -15364, -15459, -15553, -15647, -15741, -15835, -15929, -16023, -16116, -16210, -16303, -16396, -16488, -16581, -16673, -16766, -16858, -16949, -17041, -17133, -17224, -17315, -17406, -17497, -17587, -17678, -17768, -17858, -17948, -18037, -18127, -18216, -18305, -18394, -18483, -18571, -18659, -18747, -18835, -18923, -19010, -19098, -19185, -19271, -19358, -19444, -19531, -19617, -19702, -19788, -19873, -19959, -20043, -20128, -20213, -20297, -20381, -20465, -20549, -20632, -20715, -20798, -20881, -20963, -21046, -21128, -21210, -21291, -21373, -21454, -21535, -21616, -21696, -21776, -21856, -21936, -22016, -22095, -22174, -22253, -22331, -22410, -22488, -22566, -22643, -22721, -22798, -22875, -22951, -23028, -23104, -23180, -23256, -23331, -23406, -23481, -23556, -23630, -23704, -23778, -23852, -23925, -23998, -24071, -24144, -24216, -24288, -24360, -24432, -24503, -24574, -24645, -24716, -24786, -24856, -24926, -24995, -25064, -25133, -25202, -25270, -25339, -25406, -25474, -25541, -25608, -25675, -25742, -25808, -25874, -25939, -26005, -26070, -26135, -26199, -26264, -26327, -26391, -26455, -26518, -26581, -26643, -26705, -26767, -26829, -26891, -26952, -27013, -27073, -27133, -27193, -27253, -27312, -27372, -27430, -27489, -27547, -27605, -27663, -27720, -27777, -27834, -27890, -27946, -28002, -28058, -28113, -28168, -28223, -28277, -28331, -28385, -28438, -28491, -28544, -28596, -28649, -28701, -28752, -28803, -28854, -28905, -28955, -29006, -29055, -29105, -29154, -29203, -29251, -29299, -29347, -29395, -29442, -29489, -29535, -29582, -29628, -29673, -29719, -29764, -29808, -29853, -29897, -29941, -29984, -30027, -30070, -30112, -30154, -30196, -30238, -30279, -30320, -30360, -30400, -30440, -30480, -30519, -30558, -30596, -30635, -30672, -30710, -30747, -30784, -30821, -30857, -30893, -30929, -30964, -30999, -31033, -31068, -31102, -31135, -31168, -31201, -31234, -31266, -31298, -31330, -31361, -31392, -31422, -31453, -31483, -31512, -31541, -31570, -31599, -31627, -31655, -31682, -31710, -31737, -31763, -31789, -31815, -31841, -31866, -31891, -31915, -31939, -31963, -31986, -32010, -32032, -32055, -32077, -32099, -32120, -32141, -32162, -32182, -32202, -32222, -32241, -32260, -32279, -32297, -32315, -32333, -32350, -32367, -32383, -32399, -32415, -32431, -32446, -32461, -32475, -32489, -32503, -32517, -32530, -32542, -32555, -32567, -32579, -32590, -32601, -32612, -32622, -32632, -32641, -32651, -32659, -32668, -32676, -32684, -32692, -32699, -32706, -32712, -32718, -32724, -32729, -32734, -32739, -32743, -32747, -32751, -32754, -32757, -32760, -32762, -32764, -32765, -32767, -32767, -32767, 32767, 32767, 32765, 32761, 32756, 32750, 32742, 32732, 32722, 32710, 32696, 32681, 32665, 32647, 32628, 32608, 32586, 32562, 32538, 32512, 32484, 32455, 32425, 32393, 32360, 32326, 32290, 32253, 32214, 32174, 32133, 32090, 32046, 32001, 31954, 31906, 31856, 31805, 31753, 31700, 31645, 31588, 31530, 31471, 31411, 31349, 31286, 31222, 31156, 31089, 31020, 30951, 30880, 30807, 30733, 30658, 30582, 30504, 30425, 30345, 30263, 30181, 30096, 30011, 29924, 29836, 29747, 29656, 29564, 29471, 29377, 29281, 29184, 29086, 28987, 28886, 28784, 28681, 28577, 28471, 28365, 28257, 28147, 28037, 27925, 27812, 27698, 27583, 27467, 27349, 27231, 27111, 26990, 26868, 26744, 26620, 26494, 26367, 26239, 26110, 25980, 25849, 25717, 25583, 25449, 25313, 25176, 25038, 24900, 24760, 24619, 24477, 24333, 24189, 24044, 23898, 23751, 23602, 23453, 23303, 23152, 22999, 22846, 22692, 22537, 22380, 22223, 22065, 21906, 21746, 21585, 21423, 21261, 21097, 20933, 20767, 20601, 20434, 20265, 20096, 19927, 19756, 19584, 19412, 19239, 19065, 18890, 18714, 18538, 18361, 18183, 18004, 17824, 17644, 17463, 17281, 17098, 16915, 16731, 16546, 16361, 16175, 15988, 15800, 15612, 15423, 15234, 15043, 14852, 14661, 14469, 14276, 14083, 13889, 13694, 13499, 13303, 13107, 12910, 12713, 12515, 12317, 12118, 11918, 11718, 11517, 11316, 11115, 10913, 10710, 10508, 10304, 10100, 9896, 9691, 9486, 9281, 9075, 8869, 8662, 8455, 8248, 8040, 7832, 7623, 7415, 7206, 6996, 6787, 6577, 6366, 6156, 5945, 5734, 5523, 5311, 5100, 4888, 4675, 4463, 4251, 4038, 3825, 3612, 3399, 3185, 2972, 2758, 2544, 2330, 2116, 1902, 1688, 1474, 1260, 1045, 831, 617, 402, 188, -27, -241, -456, -670, -885, -1099, -1313, -1528, -1742, -1956, -2170, -2384, -2598, -2811, -3025, -3239, -3452, -3665, -3878, -4091, -4304, -4516, -4728, -4941, -5153, -5364, -5576, -5787, -5998, -6209, -6419, -6629, -6839, -7049, -7258, -7467, -7676, -7884, -8092, -8300, -8507, -8714, -8920, -9127, -9332, -9538, -9743, -9947, -10151, -10355, -10558, -10761, -10963, -11165, -11367, -11568, -11768, -11968, -12167, -12366, -12565, -12762, -12960, -13156, -13352, -13548, -13743, -13937, -14131, -14324, -14517, -14709, -14900, -15091, -15281, -15470, -15659, -15847, -16035, -16221, -16407, -16593, -16777, -16961, -17144, -17326, -17508, -17689, -17869, -18049, -18227, -18405, -18582, -18758, -18934, -19108, -19282, -19455, -19627, -19799, -19969, -20139, -20308, -20475, -20642, -20809, -20974, -21138, -21301, -21464, -21626, -21786, -21946, -22105, -22263, -22420, -22575, -22730, -22884, -23037, -23189, -23340, -23490, -23640, -23788, -23935, -24080, -24225, -24369, -24512, -24654, -24795, -24934, -25073, -25211, -25347, -25482, -25617, -25750, -25882, -26013, -26143, -26272, -26399, -26526, -26651, -26775, -26898, -27020, -27141, -27260, -27379, -27496, -27612, -27727, -27841, -27953, -28065, -28175, -28284, -28391, -28498, -28603, -28707, -28810, -28911, -29012, -29111, -29209, -29305, -29401, -29495, -29587, -29679, -29769, -29858, -29946, -30032, -30118, -30201, -30284, -30365, -30445, -30524, -30601, -30677, -30752, -30825, -30897, -30968, -31038, -31106, -31172, -31238, -31302, -31365, -31426, -31486, -31545, -31602, -31658, -31713, -31766, -31818, -31869, -31918, -31966, -32012, -32058, -32101, -32144, -32185, -32224, -32262, -32299, -32335, -32369, -32401, -32433, -32463, -32491, -32518, -32544, -32568, -32591, -32613, -32633, -32652, -32669, -32685, -32700, -32713, -32724, -32735, -32744, -32751, -32757, -32762, -32766, -32767, 32767, 32764, 32755, 32741, 32720, 32694, 32663, 32626, 32583, 32535, 32481, 32421, 32356, 32286, 32209, 32128, 32041, 31948, 31850, 31747, 31638, 31523, 31403, 31278, 31148, 31012, 30871, 30724, 30572, 30415, 30253, 30086, 29913, 29736, 29553, 29365, 29172, 28974, 28771, 28564, 28351, 28134, 27911, 27684, 27452, 27216, 26975, 26729, 26478, 26223, 25964, 25700, 25432, 25159, 24882, 24601, 24315, 24026, 23732, 23434, 23133, 22827, 22517, 22204, 21886, 21565, 21240, 20912, 20580, 20244, 19905, 19563, 19217, 18868, 18516, 18160, 17802, 17440, 17075, 16708, 16338, 15964, 15588, 15210, 14829, 14445, 14059, 13670, 13279, 12886, 12490, 12093, 11693, 11291, 10888, 10482, 10075, 9666, 9255, 8843, 8429, 8014, 7597, 7180, 6760, 6340, 5919, 5496, 5073, 4649, 4224, 3798, 3372, 2945, 2517, 2090, 1661, 1233, 804, 375, -54, -483, -911, -1340, -1768, -2197, -2624, -3052, -3479, -3905, -4330, -4755, -5179, -5602, -6024, -6445, -6865, -7284, -7702, -8118, -8533, -8946, -9358, -9768, -10177, -10584, -10989, -11392, -11793, -12192, -12589, -12984, -13377, -13767, -14155, -14541, -14924, -15305, -15683, -16058, -16430, -16800, -17167, -17531, -17892, -18249, -18604, -18956, -19304, -19649, -19990, -20329, -20663, -20994, -21322, -21646, -21966, -22282, -22595, -22904, -23208, -23509, -23806, -24099, -24387, -24672, -24952, -25228, -25499, -25766, -26029, -26288, -26541, -26791, -27035, -27275, -27511, -27741, -27967, -28188, -28405, -28616, -28823, -29024, -29221, -29412, -29599, -29780, -29957, -30128, -30294, -30455, -30611, -30761, -30906, -31046, -31181, -31310, -31434, -31552, -31665, -31773, -31875, -31972, -32063, -32149, -32229, -32304, -32373, -32437, -32495, -32547, -32594, -32635, -32671, -32701, -32726, -32745, -32758, -32766, 32767, 32754, 32717, 32658, 32577, 32473, 32348, 32200, 32029, 31837, 31624, 31388, 31131, 30853, 30553, 30232, 29891, 29530, 29148, 28746, 28324, 27883, 27423, 26944, 26447, 25931, 25398, 24847, 24279, 23695, 23095, 22478, 21846, 21199, 20538, 19863, 19174, 18472, 17757, 17030, 16291, 15541, 14781, 14010, 13230, 12441, 11643, 10837, 10024, 9204, 8377, 7545, 6708, 5866, 5020, 4171, 3319, 2464, 1608, 751, -107, -965, -1822, -2678, -3532, -4383, -5232, -6077, -6918, -7754, -8585, -9409, -10228, -11039, -11843, -12639, -13426, -14204, -14972, -15730, -16477, -17213, -17937, -18648, -19347, -20033, -20705, -21363, -22006, -22634, -23246, -23843, -24423, -24986, -25533, -26062, -26573, -27066, -27540, -27995, -28431, -28848, -29245, -29622, -29979, -30315, -30630, -30924, -31197, -31449, -31679, -31887, -32074, -32239, -32381, -32501, -32600, -32675, -32729, -32759 }; internal static readonly int[] intensity_thresholds = new int[21] { 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 36, 44, 50, 56, 62, 67, 72, 79, 88, 106, 134 }; internal static readonly int[] intensity_histeresis = new int[21] { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 8, 8 }; } internal static class VQ { private static int[] SPREAD_FACTOR = new int[3] { 15, 10, 5 }; internal static void exp_rotation1(Span X, int X_ptr, int len, int stride, int c, int s) { int num = X_ptr; int a = Inlines.NEG16(s); for (int i = 0; i < len - stride; i++) { int b = X[num]; int b2 = X[num + stride]; X[num + stride] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MAC16_16(Inlines.MULT16_16(c, b2), s, b), 15)); X[num] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MAC16_16(Inlines.MULT16_16(c, b), a, b2), 15)); num++; } num = X_ptr + (len - 2 * stride - 1); for (int i = len - 2 * stride - 1; i >= 0; i--) { int b3 = X[num]; int b4 = X[num + stride]; X[num + stride] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MAC16_16(Inlines.MULT16_16(c, b4), s, b3), 15)); X[num] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MAC16_16(Inlines.MULT16_16(c, b3), a, b4), 15)); num--; } } internal static void exp_rotation(Span X, int X_ptr, int len, int dir, int stride, int K, int spread) { int i = 0; if (2 * K >= len || spread == 0) { return; } int num = SPREAD_FACTOR[spread - 1]; int num2 = Inlines.celt_div(Inlines.MULT16_16(32767, len), len + num * K); int num3 = Inlines.HALF16(Inlines.MULT16_16_Q15(num2, num2)); int num4 = Inlines.celt_cos_norm(Inlines.EXTEND32(num3)); int num5 = Inlines.celt_cos_norm(Inlines.EXTEND32(Inlines.SUB16(32767, num3))); if (len >= 8 * stride) { for (i = 1; (i * i + i) * stride + (stride >> 2) < len; i++) { } } len = Inlines.celt_udiv(len, stride); for (int j = 0; j < stride; j++) { if (dir < 0) { if (i != 0) { exp_rotation1(X, X_ptr + j * len, len, i, num5, num4); } exp_rotation1(X, X_ptr + j * len, len, 1, num4, num5); } else { exp_rotation1(X, X_ptr + j * len, len, 1, num4, (short)(-num5)); if (i != 0) { exp_rotation1(X, X_ptr + j * len, len, i, num5, (short)(-num4)); } } } } internal static void normalise_residual(int[] iy, Span X, int X_ptr, int N, int Ryy, int gain) { int num = Inlines.celt_ilog2(Ryy) >> 1; int a = Inlines.MULT16_16_P15(Inlines.celt_rsqrt_norm(Inlines.VSHR32(Ryy, 2 * (num - 7))), gain); int num2 = 0; do { X[X_ptr + num2] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MULT16_16(a, iy[num2]), num + 1)); } while (++num2 < N); } internal static uint extract_collapse_mask(int[] iy, int N, int B) { if (B <= 1) { return 1u; } int num = Inlines.celt_udiv(N, B); uint num2 = 0u; int num3 = 0; do { uint num4 = 0u; int num5 = 0; do { num4 |= (uint)iy[num3 * num + num5]; } while (++num5 < num); num2 |= ((num4 != 0) ? 1u : 0u) << num3; } while (++num3 < B); return num2; } internal static uint alg_quant(Span X, int X_ptr, int N, int K, int spread, int B, EntropyCoder enc, Span encodedData) { int[] array = new int[N]; int[] array2 = new int[N]; int[] array3 = new int[N]; exp_rotation(X, X_ptr, N, 1, B, K, spread); int num = 0; int num2 = 0; do { int index = X_ptr + num2; array3[num2] = ((X[index] > 0) ? 1 : (-1)); X[index] = Inlines.ABS16(X[index]); array2[num2] = 0; array[num2] = 0; } while (++num2 < N); int num4; int num3 = (num4 = 0); int num5 = K; if (K > N >> 1) { num2 = 0; do { num += X[X_ptr + num2]; } while (++num2 < N); if (num <= K) { X[X_ptr] = 16384; num2 = X_ptr + 1; do { X[num2] = 0; } while (++num2 < N + X_ptr); num = 16384; } int b = Inlines.EXTRACT16(Inlines.MULT16_32_Q16(K - 1, Inlines.celt_rcp(num))); num2 = 0; do { array2[num2] = Inlines.MULT16_16_Q15(X[X_ptr + num2], b); array[num2] = array2[num2]; num4 = Inlines.MAC16_16(num4, array[num2], array[num2]); num3 = Inlines.MAC16_16(num3, X[X_ptr + num2], array[num2]); array[num2] *= 2; num5 -= array2[num2]; } while (++num2 < N); } if (num5 > N + 3) { int num6 = num5; num4 = Inlines.MAC16_16(num4, num6, num6); num4 = Inlines.MAC16_16(num4, num6, array[0]); array2[0] += num5; num5 = 0; } int num7 = 1; for (int i = 0; i < num5; i++) { int b2 = -32767; int a = 0; int shift = 1 + Inlines.celt_ilog2(K - num5 + i + 1); int num8 = 0; num4 = Inlines.ADD16(num4, 1); num2 = 0; do { int num9 = Inlines.EXTRACT16(Inlines.SHR32(Inlines.ADD32(num3, Inlines.EXTEND32(X[X_ptr + num2])), shift)); int num10 = Inlines.ADD16(num4, array[num2]); num9 = Inlines.MULT16_16_Q15(num9, num9); if (Inlines.MULT16_16(a, num9) > Inlines.MULT16_16(num10, b2)) { a = num10; b2 = num9; num8 = num2; } } while (++num2 < N); num3 = Inlines.ADD32(num3, Inlines.EXTEND32(X[X_ptr + num8])); num4 = Inlines.ADD16(num4, array[num8]); array[num8] += 2 * num7; array2[num8]++; } num2 = 0; do { X[X_ptr + num2] = Inlines.MULT16_16(array3[num2], X[X_ptr + num2]); array2[num2] = ((array3[num2] < 0) ? (-array2[num2]) : array2[num2]); } while (++num2 < N); CWRS.encode_pulses(array2, N, K, enc, encodedData); return extract_collapse_mask(array2, N, B); } internal static uint alg_unquant(Span X, int X_ptr, int N, int K, int spread, int B, EntropyCoder dec, ReadOnlySpan encodedData, int gain) { int[] array = new int[N]; int ryy = CWRS.decode_pulses(array, N, K, dec, encodedData); normalise_residual(array, X, X_ptr, N, ryy, gain); exp_rotation(X, X_ptr, N, -1, B, K, spread); return extract_collapse_mask(array, N, B); } internal static void renormalise_vector(Span X, int N, int gain) { int num = 1 + Kernels.celt_inner_prod(X, X, N); int num2 = Inlines.celt_ilog2(num) >> 1; int a = Inlines.MULT16_16_P15(Inlines.celt_rsqrt_norm(Inlines.VSHR32(num, 2 * (num2 - 7))), gain); int num3 = 0; for (int i = 0; i < N; i++) { X[num3] = Inlines.EXTRACT16(Inlines.PSHR32(Inlines.MULT16_16(a, X[num3]), num2 + 1)); num3++; } } internal static int stereo_itheta(Span X, Span Y, int stereo, int N) { int num2; int num = (num2 = 1); if (stereo != 0) { for (int i = 0; i < N; i++) { int num3 = Inlines.ADD16(Inlines.SHR16(X[i], 1), Inlines.SHR16(Y[i], 1)); int num4 = Inlines.SUB16(Inlines.SHR16(X[i], 1), Inlines.SHR16(Y[i], 1)); num = Inlines.MAC16_16(num, num3, num3); num2 = Inlines.MAC16_16(num2, num4, num4); } } else { num += Kernels.celt_inner_prod(X, X, N); num2 += Kernels.celt_inner_prod(Y, Y, N); } int x = Inlines.celt_sqrt(num); int y = Inlines.celt_sqrt(num2); return Inlines.MULT16_16_Q15(20861, Inlines.celt_atan2p(y, x)); } } } namespace Concentus.Celt.Structs { internal class AnalysisInfo { internal int valid; internal float tonality; internal float tonality_slope; internal float noisiness; internal float activity; internal float music_prob; internal int bandwidth; internal AnalysisInfo() { } internal void Assign(AnalysisInfo other) { valid = other.valid; tonality = other.tonality; tonality_slope = other.tonality_slope; noisiness = other.noisiness; activity = other.activity; music_prob = other.music_prob; bandwidth = other.bandwidth; } internal void Reset() { valid = 0; tonality = 0f; tonality_slope = 0f; noisiness = 0f; activity = 0f; music_prob = 0f; bandwidth = 0; } } internal class CeltDecoder { internal CeltMode mode; internal int overlap; internal int channels; internal int stream_channels; internal int downsample; internal int start; internal int end; internal int signalling; internal uint rng; internal int error; internal int last_pitch_index; internal int loss_count; internal int postfilter_period; internal int postfilter_period_old; internal int postfilter_gain; internal int postfilter_gain_old; internal int postfilter_tapset; internal int postfilter_tapset_old; internal readonly int[] preemph_memD = new int[2]; internal int[][] decode_mem; internal int[][] lpc; internal int[] oldEBands; internal int[] oldLogE; internal int[] oldLogE2; internal int[] backgroundLogE; private void Reset() { mode = null; overlap = 0; channels = 0; stream_channels = 0; downsample = 0; start = 0; end = 0; signalling = 0; PartialReset(); } private void PartialReset() { rng = 0u; error = 0; last_pitch_index = 0; loss_count = 0; postfilter_period = 0; postfilter_period_old = 0; postfilter_gain = 0; postfilter_gain_old = 0; postfilter_tapset = 0; postfilter_tapset_old = 0; Arrays.MemSetInt(preemph_memD, 0, 2); decode_mem = null; lpc = null; oldEBands = null; oldLogE = null; oldLogE2 = null; backgroundLogE = null; } internal void ResetState() { PartialReset(); decode_mem = new int[channels][]; lpc = new int[channels][]; for (int i = 0; i < channels; i++) { decode_mem[i] = new int[2048 + mode.overlap]; lpc[i] = new int[24]; } oldEBands = new int[2 * mode.nbEBands]; oldLogE = new int[2 * mode.nbEBands]; oldLogE2 = new int[2 * mode.nbEBands]; backgroundLogE = new int[2 * mode.nbEBands]; for (int j = 0; j < 2 * mode.nbEBands; j++) { oldLogE[j] = (oldLogE2[j] = -28672); } } internal int celt_decoder_init(int sampling_rate, int channels) { int num = opus_custom_decoder_init(CeltMode.mode48000_960_120, channels); if (num != 0) { return num; } downsample = CeltCommon.resampling_factor(sampling_rate); if (downsample == 0) { return -1; } return 0; } private int opus_custom_decoder_init(CeltMode mode, int channels) { if (channels < 0 || channels > 2) { return -1; } if (this == null) { return -7; } Reset(); this.mode = mode; overlap = mode.overlap; stream_channels = (this.channels = channels); downsample = 1; start = 0; end = this.mode.effEBands; signalling = 1; loss_count = 0; ResetState(); return 0; } internal void celt_decode_lost(int N, int LM) { int num = channels; int[][] array = new int[2][]; int[] array2 = new int[2]; CeltMode celtMode = mode; int nbEBands = celtMode.nbEBands; int num2 = celtMode.overlap; short[] eBands = celtMode.eBands; int num3 = 0; do { array[num3] = decode_mem[num3]; array2[num3] = 2048 - N; } while (++num3 < num); if (loss_count >= 5 || ((start != 0) ? true : false)) { int num4 = end; int num5 = Inlines.IMAX(start, Inlines.IMIN(num4, celtMode.effEBands)); int[][] array3 = Arrays.InitTwoDimensionalArray(num, N); int num6 = ((loss_count == 0) ? 1536 : 512); num3 = 0; do { for (int i = start; i < num4; i++) { oldEBands[num3 * nbEBands + i] = Inlines.MAX16(backgroundLogE[num3 * nbEBands + i], oldEBands[num3 * nbEBands + i] - num6); } } while (++num3 < num); uint num7 = rng; for (num3 = 0; num3 < num; num3++) { for (int i = start; i < num5; i++) { int num8 = eBands[i] << LM; int num9 = eBands[i + 1] - eBands[i] << LM; for (int j = 0; j < num9; j++) { num7 = Bands.celt_lcg_rand(num7); array3[num3][num8 + j] = (int)num7 >> 20; } VQ.renormalise_vector(MemoryExtensions.AsSpan(array3[num3]), num9, 32767); } } rng = num7; num3 = 0; do { Arrays.MemMoveInt(decode_mem[num3], N, 0, 2048 - N + (num2 >> 1)); } while (++num3 < num); CeltCommon.celt_synthesis(celtMode, array3, array, array2, oldEBands, start, num5, num, num, 0, LM, downsample, 0); } else { int a = 32767; int num10; if (loss_count == 0) { num10 = (last_pitch_index = CeltCommon.celt_plc_pitch_search(decode_mem, num)); } else { num10 = last_pitch_index; a = 26214; } int[] array4 = new int[num2]; int[] array5 = new int[1024]; Span mem = stackalloc int[24]; int[] window = celtMode.window; num3 = 0; do { int num11 = 0; int[] array6 = decode_mem[num3]; int i; for (i = 0; i < 1024; i++) { array5[i] = Inlines.ROUND16(array6[1024 + i], 12); } if (loss_count == 0) { int[] array7 = new int[25]; Autocorrelation._celt_autocorr(array5, array7, window, num2, 24, 1024); array7[0] += Inlines.SHR32(array7[0], 13); for (i = 1; i <= 24; i++) { array7[i] -= Inlines.MULT16_32_Q15(2 * i * i, array7[i]); } CeltLPC.celt_lpc(lpc[num3], array7, 24); } int num12 = Inlines.IMIN(2 * num10, 1024); for (i = 0; i < 24; i++) { mem[i] = Inlines.ROUND16(array6[2048 - num12 - 1 - i], 12); } Span span = MemoryExtensions.AsSpan(array5); Span x = span.Slice(1024 - num12); Span num13 = MemoryExtensions.AsSpan(lpc[num3]); span = MemoryExtensions.AsSpan(array5); Kernels.celt_fir(x, num13, span.Slice(1024 - num12), num12, 24, mem); int num14 = 1; int num15 = 1; int shift = Inlines.IMAX(0, 2 * Inlines.celt_zlog2(Inlines.celt_maxabs16(array5, 1024 - num12, num12)) - 20); int num16 = num12 >> 1; for (i = 0; i < num16; i++) { int num17 = array5[1024 - num16 + i]; num14 += Inlines.SHR32(Inlines.MULT16_16(num17, num17), shift); num17 = array5[1024 - 2 * num16 + i]; num15 += Inlines.SHR32(Inlines.MULT16_16(num17, num17), shift); } num14 = Inlines.MIN32(num14, num15); int b = Inlines.celt_sqrt(Inlines.frac_div32(Inlines.SHR32(num14, 1), num15)); Arrays.MemMoveInt(array6, N, 0, 2048 - N); int num18 = 1024 - num10; int num19 = N + num2; int a2 = Inlines.MULT16_16_Q15(a, b); int num20; i = (num20 = 0); while (i < num19) { if (num20 >= num10) { num20 -= num10; a2 = Inlines.MULT16_16_Q15(a2, b); } array6[2048 - N + i] = Inlines.SHL32(Inlines.MULT16_16_Q15(a2, array5[num18 + num20]), 12); int num21 = Inlines.ROUND16(array6[1024 - N + num18 + num20], 12); num11 += Inlines.SHR32(Inlines.MULT16_16(num21, num21), 8); i++; num20++; } for (i = 0; i < 24; i++) { mem[i] = Inlines.ROUND16(array6[2048 - N - 1 - i], 12); } span = MemoryExtensions.AsSpan(array6); Span x2 = span.Slice(2048 - N); int[] den = lpc[num3]; span = MemoryExtensions.AsSpan(array6); CeltLPC.celt_iir(x2, den, span.Slice(2048 - N), num19, 24, mem); int num22 = 0; for (i = 0; i < num19; i++) { int num23 = Inlines.ROUND16(array6[2048 - N + i], 12); num22 += Inlines.SHR32(Inlines.MULT16_16(num23, num23), 8); } if (num11 <= Inlines.SHR32(num22, 2)) { for (i = 0; i < num19; i++) { array6[2048 - N + i] = 0; } } else if (num11 < num22) { int num24 = Inlines.celt_sqrt(Inlines.frac_div32(Inlines.SHR32(num11, 1) + 1, num22 + 1)); for (i = 0; i < num2; i++) { int a3 = 32767 - Inlines.MULT16_16_Q15(window[i], 32767 - num24); array6[2048 - N + i] = Inlines.MULT16_32_Q15(a3, array6[2048 - N + i]); } for (i = num2; i < num19; i++) { array6[2048 - N + i] = Inlines.MULT16_32_Q15(num24, array6[2048 - N + i]); } } CeltCommon.comb_filter(array4, 0, array6, 2048, postfilter_period, postfilter_period, num2, -postfilter_gain, -postfilter_gain, postfilter_tapset, postfilter_tapset, null, 0); for (i = 0; i < num2 / 2; i++) { array6[2048 + i] = Inlines.MULT16_32_Q15(window[i], array4[num2 - 1 - i]) + Inlines.MULT16_32_Q15(window[num2 - i - 1], array4[i]); } } while (++num3 < num); } loss_count++; } internal int celt_decode_with_ec(ReadOnlySpan data, int data_ptr, int len, Span pcm, int pcm_ptr, int frame_size, EntropyCoder dec, int accum) { int[][] array = new int[2][]; int[] array2 = new int[2]; int num = channels; int intensity = 0; int dual_stereo = 0; int num2 = 0; int num3 = stream_channels; CeltMode celtMode = mode; int nbEBands = celtMode.nbEBands; int num4 = celtMode.overlap; short[] eBands = celtMode.eBands; int num5 = start; int num6 = end; frame_size *= downsample; int[] array3 = oldEBands; int[] array4 = oldLogE; int[] array5 = oldLogE2; int[] array6 = backgroundLogE; int i; for (i = 0; i <= celtMode.maxLM && celtMode.shortMdctSize << i != frame_size; i++) { } if (i > celtMode.maxLM) { return -1; } int num7 = 1 << i; if (len < 0 || len > 1275 || pcm.IsEmpty) { return -1; } int num8 = num7 * celtMode.shortMdctSize; int num9 = 0; do { array[num9] = decode_mem[num9]; array2[num9] = 2048 - num8; } while (++num9 < num); int num10 = num6; if (num10 > celtMode.effEBands) { num10 = celtMode.effEBands; } if (data.IsEmpty || len <= 1) { celt_decode_lost(num8, i); CeltCommon.deemphasis(array, array2, pcm, pcm_ptr, num8, num, downsample, celtMode.preemph, preemph_memD, accum); return frame_size / downsample; } if (dec == null) { dec = new EntropyCoder(); dec.dec_init(data.Slice(data_ptr), (uint)len); } if (num3 == 1) { for (int j = 0; j < nbEBands; j++) { array3[j] = Inlines.MAX16(array3[j], array3[nbEBands + j]); } } int num11 = len * 8; int num12 = dec.tell(); int num13 = ((num12 >= num11) ? 1 : ((num12 == 1) ? dec.dec_bit_logp(data.Slice(data_ptr), 15u) : 0)); if (num13 != 0) { num12 = len * 8; dec.nbits_total += num12 - dec.tell(); } int g = 0; int t = 0; int tapset = 0; if (num5 == 0 && num12 + 16 <= num11) { if (dec.dec_bit_logp(data.Slice(data_ptr), 1u) != 0) { int num14 = (int)dec.dec_uint(data.Slice(data_ptr), 6u); t = (16 << num14) + (int)dec.dec_bits(data.Slice(data_ptr), (uint)(4 + num14)) - 1; int num15 = (int)dec.dec_bits(data.Slice(data_ptr), 3u); if (dec.tell() + 2 <= num11) { tapset = dec.dec_icdf(data.Slice(data_ptr), Tables.tapset_icdf, 2u); } g = 3072 * (num15 + 1); } num12 = dec.tell(); } int num16; if (i > 0 && num12 + 3 <= num11) { num16 = dec.dec_bit_logp(data.Slice(data_ptr), 3u); num12 = dec.tell(); } else { num16 = 0; } int shortBlocks = ((num16 != 0) ? num7 : 0); int intra = ((num12 + 3 <= num11) ? dec.dec_bit_logp(data.Slice(data_ptr), 3u) : 0); QuantizeBands.unquant_coarse_energy(celtMode, num5, num6, array3, intra, dec, data.Slice(data_ptr), num3, i); int[] tf_res = new int[nbEBands]; CeltCommon.tf_decode(num5, num6, num16, tf_res, i, dec, data.Slice(data_ptr)); num12 = dec.tell(); int spread = 2; if (num12 + 4 <= num11) { spread = dec.dec_icdf(data.Slice(data_ptr), Tables.spread_icdf, 5u); } int[] array7 = new int[nbEBands]; CeltCommon.init_caps(celtMode, array7, i, num3); int[] array8 = new int[nbEBands]; int num17 = 6; num11 <<= 3; num12 = (int)dec.tell_frac(); for (int j = num5; j < num6; j++) { int num18 = num3 * (eBands[j + 1] - eBands[j]) << i; int num19 = Inlines.IMIN(num18 << 3, Inlines.IMAX(48, num18)); int num20 = num17; int num21 = 0; while (num12 + (num20 << 3) < num11 && num21 < array7[j]) { int num22 = dec.dec_bit_logp(data.Slice(data_ptr), (uint)num20); num12 = (int)dec.tell_frac(); if (num22 == 0) { break; } num21 += num19; num11 -= num19; num20 = 1; } array8[j] = num21; if (num21 > 0) { num17 = Inlines.IMAX(2, num17 - 1); } } int[] array9 = new int[nbEBands]; int alloc_trim = ((num12 + 48 <= num11) ? dec.dec_icdf(data.Slice(data_ptr), Tables.trim_icdf, 7u) : 5); int num23 = (len * 8 << 3) - (int)dec.tell_frac() - 1; int num24 = ((num16 != 0 && i >= 2 && num23 >= i + 2 << 3) ? 8 : 0); num23 -= num24; int[] pulses = new int[nbEBands]; int[] fine_priority = new int[nbEBands]; int balance; int codedBands = Rate.compute_allocation_decode(celtMode, num5, num6, array8, array7, alloc_trim, ref intensity, ref dual_stereo, num23, out balance, pulses, array9, fine_priority, num3, i, dec, data.Slice(data_ptr), 0, 0); QuantizeBands.unquant_fine_energy(celtMode, num5, num6, array3, array9, dec, data.Slice(data_ptr), num3); num9 = 0; do { Arrays.MemMoveInt(decode_mem[num9], num8, 0, 2048 - num8 + num4 / 2); } while (++num9 < num); byte[] collapse_masks = new byte[num3 * nbEBands]; int[][] array10 = Arrays.InitTwoDimensionalArray(num3, num8); Bands.quant_all_bands_decode(0, celtMode, num5, num6, array10[0], (num3 == 2) ? array10[1] : null, collapse_masks, null, pulses, shortBlocks, spread, dual_stereo, intensity, tf_res, len * 64 - num24, balance, dec, data.Slice(data_ptr), i, codedBands, ref rng); if (num24 > 0) { num2 = (int)dec.dec_bits(data.Slice(data_ptr), 1u); } QuantizeBands.unquant_energy_finalise(celtMode, num5, num6, array3, array9, fine_priority, len * 8 - dec.tell(), dec, data.Slice(data_ptr), num3); if (num2 != 0) { Bands.anti_collapse(celtMode, array10, collapse_masks, i, num3, num8, num5, num6, array3, array4, array5, pulses, rng); } if (num13 != 0) { for (int j = 0; j < num3 * nbEBands; j++) { array3[j] = -28672; } } CeltCommon.celt_synthesis(celtMode, array10, array, array2, array3, num5, num10, num3, num, num16, i, downsample, num13); num9 = 0; do { postfilter_period = Inlines.IMAX(postfilter_period, 15); postfilter_period_old = Inlines.IMAX(postfilter_period_old, 15); CeltCommon.comb_filter(array[num9], array2[num9], array[num9], array2[num9], postfilter_period_old, postfilter_period, celtMode.shortMdctSize, postfilter_gain_old, postfilter_gain, postfilter_tapset_old, postfilter_tapset, celtMode.window, num4); if (i != 0) { CeltCommon.comb_filter(array[num9], array2[num9] + celtMode.shortMdctSize, array[num9], array2[num9] + celtMode.shortMdctSize, postfilter_period, t, num8 - celtMode.shortMdctSize, postfilter_gain, g, postfilter_tapset, tapset, celtMode.window, num4); } } while (++num9 < num); postfilter_period_old = postfilter_period; postfilter_gain_old = postfilter_gain; postfilter_tapset_old = postfilter_tapset; postfilter_period = t; postfilter_gain = g; postfilter_tapset = tapset; if (i != 0) { postfilter_period_old = postfilter_period; postfilter_gain_old = postfilter_gain; postfilter_tapset_old = postfilter_tapset; } if (num3 == 1) { Arrays.MemCopy(array3, 0, array3, nbEBands, nbEBands); } if (num16 == 0) { Arrays.MemCopy(array4, 0, array5, 0, 2 * nbEBands); Arrays.MemCopy(array3, 0, array4, 0, 2 * nbEBands); int num25 = ((loss_count >= 10) ? 1024 : num7); for (int j = 0; j < 2 * nbEBands; j++) { array6[j] = Inlines.MIN16(array6[j] + num25, array3[j]); } } else { for (int j = 0; j < 2 * nbEBands; j++) { array4[j] = Inlines.MIN16(array4[j], array3[j]); } } num9 = 0; do { for (int j = 0; j < num5; j++) { array3[num9 * nbEBands + j] = 0; array4[num9 * nbEBands + j] = (array5[num9 * nbEBands + j] = -28672); } for (int j = num6; j < nbEBands; j++) { array3[num9 * nbEBands + j] = 0; array4[num9 * nbEBands + j] = (array5[num9 * nbEBands + j] = -28672); } } while (++num9 < 2); rng = dec.rng; CeltCommon.deemphasis(array, array2, pcm, pcm_ptr, num8, num, downsample, celtMode.preemph, preemph_memD, accum); loss_count = 0; if (dec.tell() > 8 * len) { return -3; } if (dec.get_error() != 0) { error = 1; } return frame_size / downsample; } internal void SetStartBand(int value) { if (value < 0 || value >= mode.nbEBands) { throw new ArgumentException("Start band above max number of ebands (or negative)"); } start = value; } internal void SetEndBand(int value) { if (value < 1 || value > mode.nbEBands) { throw new ArgumentException("End band above max number of ebands (or less than 1)"); } end = value; } internal void SetChannels(int value) { if (value < 1 || value > 2) { throw new ArgumentException("Channel count must be 1 or 2"); } stream_channels = value; } internal int GetAndClearError() { int result = error; error = 0; return result; } internal int GetLookahead() { return overlap / downsample; } internal int GetPitch() { return postfilter_period; } internal CeltMode GetMode() { return mode; } internal void SetSignalling(int value) { signalling = value; } internal uint GetFinalRange() { return rng; } } internal class CeltEncoder { internal CeltMode mode; internal int channels; internal int stream_channels; internal int force_intra; internal int clip; internal int disable_pf; internal int complexity; internal int upsample; internal int start; internal int end; internal int bitrate; internal int vbr; internal int signalling; internal int constrained_vbr; internal int loss_rate; internal int lsb_depth; internal OpusFramesize variable_duration; internal int lfe; internal uint rng; internal int spread_decision; internal int delayedIntra; internal int tonal_average; internal int lastCodedBands; internal int hf_average; internal int tapset_decision; internal int prefilter_period; internal int prefilter_gain; internal int prefilter_tapset; internal int consec_transient; internal AnalysisInfo analysis = new AnalysisInfo(); internal readonly int[] preemph_memE = new int[2]; internal readonly int[] preemph_memD = new int[2]; internal int vbr_reservoir; internal int vbr_drift; internal int vbr_offset; internal int vbr_count; internal int overlap_max; internal int stereo_saving; internal int intensity; internal int[] energy_mask; internal int spec_avg; internal int[][] in_mem; internal int[][] prefilter_mem; internal int[][] oldBandE; internal int[][] oldLogE; internal int[][] oldLogE2; private void Reset() { mode = null; channels = 0; stream_channels = 0; force_intra = 0; clip = 0; disable_pf = 0; complexity = 0; upsample = 0; start = 0; end = 0; bitrate = 0; vbr = 0; signalling = 0; constrained_vbr = 0; loss_rate = 0; lsb_depth = 0; variable_duration = (OpusFramesize)0; lfe = 0; PartialReset(); } private void PartialReset() { rng = 0u; spread_decision = 0; delayedIntra = 0; tonal_average = 0; lastCodedBands = 0; hf_average = 0; tapset_decision = 0; prefilter_period = 0; prefilter_gain = 0; prefilter_tapset = 0; consec_transient = 0; analysis.Reset(); preemph_memE[0] = 0; preemph_memE[1] = 0; preemph_memD[0] = 0; preemph_memD[1] = 0; vbr_reservoir = 0; vbr_drift = 0; vbr_offset = 0; vbr_count = 0; overlap_max = 0; stereo_saving = 0; intensity = 0; energy_mask = null; spec_avg = 0; in_mem = null; prefilter_mem = null; oldBandE = null; oldLogE = null; oldLogE2 = null; } internal void ResetState() { PartialReset(); in_mem = Arrays.InitTwoDimensionalArray(channels, mode.overlap); prefilter_mem = Arrays.InitTwoDimensionalArray(channels, 1024); oldBandE = Arrays.InitTwoDimensionalArray(channels, mode.nbEBands); oldLogE = Arrays.InitTwoDimensionalArray(channels, mode.nbEBands); oldLogE2 = Arrays.InitTwoDimensionalArray(channels, mode.nbEBands); for (int i = 0; i < mode.nbEBands; i++) { oldLogE[0][i] = (oldLogE2[0][i] = -28672); } if (channels == 2) { for (int i = 0; i < mode.nbEBands; i++) { oldLogE[1][i] = (oldLogE2[1][i] = -28672); } } vbr_offset = 0; delayedIntra = 1; spread_decision = 2; tonal_average = 256; hf_average = 0; tapset_decision = 0; } internal int opus_custom_encoder_init_arch(CeltMode mode, int channels) { if (channels < 0 || channels > 2) { return -1; } if (this == null || mode == null) { return -7; } Reset(); this.mode = mode; stream_channels = (this.channels = channels); upsample = 1; start = 0; end = this.mode.effEBands; signalling = 1; constrained_vbr = 1; clip = 1; bitrate = -1; vbr = 0; force_intra = 0; complexity = 5; lsb_depth = 24; ResetState(); return 0; } internal int celt_encoder_init(int sampling_rate, int channels) { int num = opus_custom_encoder_init_arch(CeltMode.mode48000_960_120, channels); if (num != 0) { return num; } upsample = CeltCommon.resampling_factor(sampling_rate); return 0; } internal int run_prefilter(int[][] input, int[][] prefilter_mem, int CC, int N, int prefilter_tapset, out int pitch, out int gain, out int qgain, int enabled, int nbAvailableBytes) { int[][] array = new int[CC][]; CeltMode celtMode = mode; int overlap = celtMode.overlap; for (int i = 0; i < CC; i++) { array[i] = new int[N + 1024]; } int num = 0; do { Arrays.MemCopy(prefilter_mem[num], 0, array[num], 0, 1024); Arrays.MemCopy(input[num], overlap, array[num], 1024, N); } while (++num < CC); int pitch2; int b; if (enabled != 0) { int[] array2 = new int[1024 + N >> 1]; Pitch.pitch_downsample(array, array2, 1024 + N, CC); Pitch.pitch_search(array2, 512, array2, N, 979, out pitch2); pitch2 = 1024 - pitch2; b = Pitch.remove_doubling(array2, 1024, 15, N, ref pitch2, prefilter_period, prefilter_gain); if (pitch2 > 1022) { pitch2 = 1022; } b = Inlines.MULT16_16_Q15(22938, b); if (loss_rate > 2) { b = Inlines.HALF32(b); } if (loss_rate > 4) { b = Inlines.HALF32(b); } if (loss_rate > 8) { b = 0; } } else { b = 0; pitch2 = 15; } int num2 = 6554; if (Inlines.abs(pitch2 - prefilter_period) * 10 > pitch2) { num2 += 6554; } if (nbAvailableBytes < 25) { num2 += 3277; } if (nbAvailableBytes < 35) { num2 += 3277; } if (prefilter_gain > 13107) { num2 -= 3277; } if (prefilter_gain > 18022) { num2 -= 3277; } num2 = Inlines.MAX16(num2, 6554); int result; int num3; if (b < num2) { b = 0; result = 0; num3 = 0; } else { if (Inlines.ABS32(b - prefilter_gain) < 3277) { b = prefilter_gain; } num3 = (b + 1536 >> 10) / 3 - 1; num3 = Inlines.IMAX(0, Inlines.IMIN(7, num3)); b = 3072 * (num3 + 1); result = 1; } num = 0; do { int num4 = celtMode.shortMdctSize - overlap; prefilter_period = Inlines.IMAX(prefilter_period, 15); Arrays.MemCopy(in_mem[num], 0, input[num], 0, overlap); if (num4 != 0) { CeltCommon.comb_filter(input[num], overlap, array[num], 1024, prefilter_period, prefilter_period, num4, -prefilter_gain, -prefilter_gain, this.prefilter_tapset, this.prefilter_tapset, null, 0); } CeltCommon.comb_filter(input[num], overlap + num4, array[num], 1024 + num4, prefilter_period, pitch2, N - num4, -prefilter_gain, -b, this.prefilter_tapset, prefilter_tapset, celtMode.window, overlap); Arrays.MemCopy(input[num], N, in_mem[num], 0, overlap); if (N > 1024) { Arrays.MemCopy(array[num], N, prefilter_mem[num], 0, 1024); continue; } Arrays.MemMoveInt(prefilter_mem[num], N, 0, 1024 - N); Arrays.MemCopy(array[num], 1024, prefilter_mem[num], 1024 - N, N); } while (++num < CC); gain = b; pitch = pitch2; qgain = num3; return result; } internal int celt_encode_with_ec(Span pcm, int pcm_ptr, int frame_size, Span compressed, int compressed_ptr, int nbCompressedBytes, EntropyCoder enc) { int num = 0; int num2 = 0; int num3 = channels; int num4 = stream_channels; int pitch = 15; int gain = 0; int dual_stereo = 0; int num5 = 0; int num6 = 0; int num7 = 0; int tf_chan = 0; int pitch_change = 0; int num8 = 0; int surround_masking = 0; int num9 = 0; int surround_trim = 0; int num10 = 510000; CeltMode celtMode = mode; int nbEBands = celtMode.nbEBands; int overlap = celtMode.overlap; short[] eBands = celtMode.eBands; int num11 = start; int num12 = end; int tf_estimate = 0; if (nbCompressedBytes < 2 || pcm.IsEmpty) { return -1; } frame_size *= upsample; int i; for (i = 0; i <= celtMode.maxLM && celtMode.shortMdctSize << i != frame_size; i++) { } if (i > celtMode.maxLM) { return -1; } int num13 = 1 << i; int num14 = num13 * celtMode.shortMdctSize; int num16; int num15; if (enc == null) { num15 = 1; num16 = 0; } else { num15 = enc.tell(); num16 = num15 + 4 >> 3; } nbCompressedBytes = Inlines.IMIN(nbCompressedBytes, 1275); int num17 = nbCompressedBytes - num16; int num19; int num20; if (vbr != 0 && bitrate != -1) { int num18 = celtMode.Fs >> 3; num19 = (bitrate * frame_size + (num18 >> 1)) / num18; num20 = num19 >> 6; } else { num19 = 0; int num21 = bitrate * frame_size; if (num15 > 1) { num21 += num15; } if (bitrate != -1) { nbCompressedBytes = Inlines.IMAX(2, Inlines.IMIN(nbCompressedBytes, (num21 + 4 * celtMode.Fs) / (8 * celtMode.Fs) - ((signalling != 0) ? 1 : 0))); } num20 = nbCompressedBytes; } if (bitrate != -1) { num10 = bitrate - (40 * num4 + 20) * ((400 >> i) - 50); } if (enc == null) { enc = new EntropyCoder(); enc.enc_init((uint)nbCompressedBytes); } if (num19 > 0 && constrained_vbr != 0) { int num22 = num19; int num23 = Inlines.IMIN(Inlines.IMAX((num15 == 1) ? 2 : 0, num19 + num22 - vbr_reservoir >> 6), num17); if (num23 < num17) { nbCompressedBytes = num16 + num23; num17 = num23; enc.enc_shrink(compressed.Slice(compressed_ptr), (uint)nbCompressedBytes); } } int num24 = nbCompressedBytes * 8; int num25 = num12; if (num25 > celtMode.effEBands) { num25 = celtMode.effEBands; } int[][] array = Arrays.InitTwoDimensionalArray(num3, num14 + overlap); int a = Inlines.MAX32(overlap_max, Inlines.celt_maxabs32(pcm, pcm_ptr, num4 * (num14 - overlap) / upsample)); overlap_max = Inlines.celt_maxabs32(pcm, pcm_ptr + num4 * (num14 - overlap) / upsample, num4 * overlap / upsample); num7 = ((Inlines.MAX32(a, overlap_max) == 0) ? 1 : 0); if (num15 == 1) { enc.enc_bit_logp(compressed.Slice(compressed_ptr), num7, 15u); } else { num7 = 0; } if (num7 != 0) { if (num19 > 0) { num20 = (nbCompressedBytes = Inlines.IMIN(nbCompressedBytes, num16 + 2)); num24 = nbCompressedBytes * 8; num17 = 2; enc.enc_shrink(compressed.Slice(compressed_ptr), (uint)nbCompressedBytes); } num15 = nbCompressedBytes * 8; enc.nbits_total += num15 - enc.tell(); } int num26 = 0; do { int num27 = 0; CeltCommon.celt_preemphasis(pcm, pcm_ptr + num26, array[num26], overlap, num14, num3, upsample, celtMode.preemph, ref preemph_memE[num26], num27); } while (++num26 < num3); int enabled = ((((lfe != 0 && num17 > 3) || num17 > 12 * num4) && num11 == 0 && num7 == 0 && disable_pf == 0 && complexity >= 5 && (consec_transient == 0 || i == 3 || variable_duration != OpusFramesize.OPUS_FRAMESIZE_VARIABLE)) ? 1 : 0); num5 = tapset_decision; int qgain; int num28 = run_prefilter(array, prefilter_mem, num3, num14, num5, out pitch, out gain, out qgain, enabled, num17); if ((gain > 13107 || prefilter_gain > 13107) && (analysis.valid == 0 || (double)analysis.tonality > 0.3) && ((double)pitch > 1.26 * (double)prefilter_period || (double)pitch < 0.79 * (double)prefilter_period)) { pitch_change = 1; } if (num28 == 0) { if (num11 == 0 && num15 + 16 <= num24) { enc.enc_bit_logp(compressed.Slice(compressed_ptr), 0, 1u); } } else { enc.enc_bit_logp(compressed.Slice(compressed_ptr), 1, 1u); pitch++; int num29 = Inlines.EC_ILOG((uint)pitch) - 5; enc.enc_uint(compressed.Slice(compressed_ptr), (uint)num29, 6u); enc.enc_bits(compressed.Slice(compressed_ptr), (uint)(pitch - (16 << num29)), (uint)(4 + num29)); pitch--; enc.enc_bits(compressed.Slice(compressed_ptr), (uint)qgain, 3u); enc.enc_icdf(compressed.Slice(compressed_ptr), num5, Tables.tapset_icdf, 2u); } num2 = 0; num = 0; if (complexity >= 1 && lfe == 0) { num2 = CeltCommon.transient_analysis(array, num14 + overlap, num3, out tf_estimate, out tf_chan); } if (i > 0 && enc.tell() + 3 <= num24) { if (num2 != 0) { num = num13; } } else { num2 = 0; num8 = 1; } int[][] array2 = Arrays.InitTwoDimensionalArray(num3, num14); int[][] array3 = Arrays.InitTwoDimensionalArray(num3, nbEBands); int[][] array4 = Arrays.InitTwoDimensionalArray(num3, nbEBands); int num30 = ((num != 0 && complexity >= 8) ? 1 : 0); int[][] array5 = Arrays.InitTwoDimensionalArray(num3, nbEBands); if (num30 != 0) { CeltCommon.compute_mdcts(celtMode, 0, array, array2, num4, num3, i, upsample); Bands.compute_band_energies(celtMode, array2, array3, num25, num4, i); QuantizeBands.amp2Log2(celtMode, num25, num12, array3, array5, num4); for (int j = 0; j < nbEBands; j++) { array5[0][j] += Inlines.HALF16(Inlines.SHL16(i, 10)); } if (num4 == 2) { for (int j = 0; j < nbEBands; j++) { array5[1][j] += Inlines.HALF16(Inlines.SHL16(i, 10)); } } } CeltCommon.compute_mdcts(celtMode, num, array, array2, num4, num3, i, upsample); if (num3 == 2 && num4 == 1) { tf_chan = 0; } Bands.compute_band_energies(celtMode, array2, array3, num25, num4, i); if (lfe != 0) { for (int j = 2; j < num12; j++) { array3[0][j] = Inlines.IMIN(array3[0][j], Inlines.MULT16_32_Q15((short)3, array3[0][0])); array3[0][j] = Inlines.MAX32(array3[0][j], 1); } } QuantizeBands.amp2Log2(celtMode, num25, num12, array3, array4, num4); int[] array6 = new int[num4 * nbEBands]; if (num11 == 0 && energy_mask != null && lfe == 0) { int num31 = 0; int num32 = 0; int num33 = 0; int num34 = Inlines.IMAX(2, lastCodedBands); for (num26 = 0; num26 < num4; num26++) { for (int j = 0; j < num34; j++) { int num35 = Inlines.MAX16(Inlines.MIN16(energy_mask[nbEBands * num26 + j], 256), -2048); if (num35 > 0) { num35 = Inlines.HALF16(num35); } num31 += Inlines.MULT16_16(num35, eBands[j + 1] - eBands[j]); num33 += eBands[j + 1] - eBands[j]; num32 += Inlines.MULT16_16(num35, 1 + 2 * j - num34); } } num31 = Inlines.DIV32_16(num31, num33); num31 += 205; num32 = num32 * 6 / (num4 * (num34 - 1) * (num34 + 1) * num34); num32 = Inlines.HALF32(num32); num32 = Inlines.MAX32(Inlines.MIN32(num32, 32), -32); int k; for (k = 0; eBands[k + 1] < eBands[num34] / 2; k++) { } int num36 = 0; for (int j = 0; j < num34; j++) { int num37 = num31 + num32 * (j - k); int a2 = ((num4 != 2) ? energy_mask[j] : Inlines.MAX16(energy_mask[j], energy_mask[nbEBands + j])); a2 = Inlines.MIN16(a2, 0); a2 -= num37; if (a2 > 256) { array6[j] = a2 - 256; num36++; } } if (num36 >= 3) { num31 += 256; if (num31 > 0) { num31 = 0; num32 = 0; Arrays.MemSetInt(array6, 0, num34); } else { for (int j = 0; j < num34; j++) { array6[j] = Inlines.MAX16(0, array6[j] - 256); } } } num31 += 205; surround_trim = 64 * num32; surround_masking = num31; } if (lfe == 0) { int num38 = -10240; int num39 = 0; int num40 = ((num != 0) ? Inlines.HALF16(Inlines.SHL16(i, 10)) : 0); for (int j = num11; j < num12; j++) { num38 = Inlines.MAX16(num38 - 1024, array4[0][j] - num40); if (num4 == 2) { num38 = Inlines.MAX16(num38, array4[1][j] - num40); } num39 += num38; } num39 /= num12 - num11; num9 = Inlines.SUB16(num39, spec_avg); num9 = Inlines.MIN16(3072, Inlines.MAX16(-1536, num9)); spec_avg += (short)Inlines.MULT16_16_Q15(655, num9); } if (num30 == 0) { Arrays.MemCopy(array4[0], 0, array5[0], 0, nbEBands); if (num4 == 2) { Arrays.MemCopy(array4[1], 0, array5[1], 0, nbEBands); } } if (i > 0 && enc.tell() + 3 <= num24 && num2 == 0 && complexity >= 5 && lfe == 0 && CeltCommon.patch_transient_decision(array4, oldBandE, nbEBands, num11, num12, num4) != 0) { num2 = 1; num = num13; CeltCommon.compute_mdcts(celtMode, num, array, array2, num4, num3, i, upsample); Bands.compute_band_energies(celtMode, array2, array3, num25, num4, i); QuantizeBands.amp2Log2(celtMode, num25, num12, array3, array4, num4); for (int j = 0; j < nbEBands; j++) { array5[0][j] += Inlines.HALF16(Inlines.SHL16(i, 10)); } if (num4 == 2) { for (int j = 0; j < nbEBands; j++) { array5[1][j] += Inlines.HALF16(Inlines.SHL16(i, 10)); } } tf_estimate = 3277; } if (i > 0 && enc.tell() + 3 <= num24) { enc.enc_bit_logp(compressed.Slice(compressed_ptr), num2, 3u); } int[][] array7 = Arrays.InitTwoDimensionalArray(num4, num14); Bands.normalise_bands(celtMode, array2, array7, array3, num25, num4, num13); int[] array8 = new int[nbEBands]; int tf_select; if (num20 >= 15 * num4 && num11 == 0 && complexity >= 2 && lfe == 0) { int num41 = ((num20 < 40) ? 12 : ((num20 < 60) ? 6 : ((num20 >= 100) ? 3 : 4))); num41 *= 2; tf_select = CeltCommon.tf_analysis(celtMode, num25, num2, array8, num41, array7, num14, i, out var _, tf_estimate, tf_chan); for (int j = num25; j < num12; j++) { array8[j] = array8[num25 - 1]; } } else { int tf_sum = 0; for (int j = 0; j < num12; j++) { array8[j] = num2; } tf_select = 0; } int[][] error = Arrays.InitTwoDimensionalArray(num4, nbEBands); QuantizeBands.quant_coarse_energy(celtMode, num11, num12, num25, array4, oldBandE, (uint)num24, error, enc, compressed.Slice(compressed_ptr), num4, i, num17, force_intra, ref delayedIntra, (complexity >= 4) ? 1 : 0, loss_rate, lfe); CeltCommon.tf_encode(num11, num12, num2, array8, i, tf_select, enc, compressed.Slice(compressed_ptr)); if (enc.tell() + 4 <= num24) { if (lfe != 0) { tapset_decision = 0; spread_decision = 2; } else if (num != 0 || complexity < 3 || num17 < 10 * num4 || num11 != 0) { if (complexity == 0) { spread_decision = 0; } else { spread_decision = 2; } } else { spread_decision = Bands.spreading_decision(celtMode, array7, ref tonal_average, spread_decision, ref hf_average, ref tapset_decision, (num28 != 0 && num == 0) ? 1 : 0, num25, num4, num13); } enc.enc_icdf(compressed.Slice(compressed_ptr), spread_decision, Tables.spread_icdf, 5u); } int[] array9 = new int[nbEBands]; int tot_boost_; int maxDepth = CeltCommon.dynalloc_analysis(array4, array5, nbEBands, num11, num12, num4, array9, lsb_depth, celtMode.logN, num2, vbr, constrained_vbr, eBands, i, num20, out tot_boost_, lfe, array6); if (lfe != 0) { array9[0] = Inlines.IMIN(8, num20 / 3); } int[] array10 = new int[nbEBands]; CeltCommon.init_caps(celtMode, array10, i, num4); int num42 = 6; num24 <<= 3; int num43 = 0; num15 = (int)enc.tell_frac(); for (int j = num11; j < num12; j++) { int num44 = num4 * (eBands[j + 1] - eBands[j]) << i; int num45 = Inlines.IMIN(num44 << 3, Inlines.IMAX(48, num44)); int num46 = num42; int num47 = 0; int num48 = 0; while (num15 + (num46 << 3) < num24 - num43 && num47 < array10[j]) { int num49 = ((num48 < array9[j]) ? 1 : 0); enc.enc_bit_logp(compressed.Slice(compressed_ptr), num49, (uint)num46); num15 = (int)enc.tell_frac(); if (num49 == 0) { break; } num47 += num45; num43 += num45; num46 = 1; num48++; } if (num48 != 0) { num42 = Inlines.IMAX(2, num42 - 1); } array9[j] = num47; } if (num4 == 2) { if (i != 0) { dual_stereo = CeltCommon.stereo_analysis(celtMode, array7, i); } intensity = Bands.hysteresis_decision(num10 / 1000, Tables.intensity_thresholds, Tables.intensity_histeresis, 21, intensity); intensity = Inlines.IMIN(num12, Inlines.IMAX(num11, intensity)); } int num50 = 5; if (num15 + 48 <= num24 - num43) { num50 = ((lfe == 0) ? CeltCommon.alloc_trim_analysis(celtMode, array7, array4, num12, i, num4, analysis, ref stereo_saving, tf_estimate, intensity, surround_trim) : 5); enc.enc_icdf(compressed.Slice(compressed_ptr), num50, Tables.trim_icdf, 7u); num15 = (int)enc.tell_frac(); } if (num19 > 0) { int num51 = celtMode.maxLM - i; nbCompressedBytes = Inlines.IMIN(nbCompressedBytes, 1275 >> 3 - i); int num52 = num19 - (40 * num4 + 20 << 3); if (constrained_vbr != 0) { num52 += vbr_offset >> num51; } int num53 = CeltCommon.compute_vbr(celtMode, analysis, num52, i, num10, lastCodedBands, num4, intensity, constrained_vbr, stereo_saving, tot_boost_, tf_estimate, pitch_change, maxDepth, variable_duration, lfe, (energy_mask != null) ? 1 : 0, surround_masking, num9); num53 += num15; int a3 = (num15 + num43 + 64 - 1 >> 6) + 2 - num16; num17 = num53 + 32 >> 6; num17 = Inlines.IMAX(a3, num17); num17 = Inlines.IMIN(nbCompressedBytes, num17 + num16) - num16; int num54 = num53 - num19; num53 = num17 << 6; if (num7 != 0) { num17 = 2; num53 = 128; num54 = 0; } int a4; if (vbr_count < 970) { vbr_count++; a4 = Inlines.celt_rcp(Inlines.SHL32(vbr_count + 20, 16)); } else { a4 = 33; } if (constrained_vbr != 0) { vbr_reservoir += num53 - num19; } if (constrained_vbr != 0) { vbr_drift += Inlines.MULT16_32_Q15(a4, num54 * (1 << num51) - vbr_offset - vbr_drift); vbr_offset = -vbr_drift; } if (constrained_vbr != 0 && vbr_reservoir < 0) { int num55 = -vbr_reservoir / 64; num17 += ((num7 == 0) ? num55 : 0); vbr_reservoir = 0; } nbCompressedBytes = Inlines.IMIN(nbCompressedBytes, num17 + num16); enc.enc_shrink(compressed.Slice(compressed_ptr), (uint)nbCompressedBytes); } int[] array11 = new int[nbEBands]; int[] pulses = new int[nbEBands]; int[] fine_priority = new int[nbEBands]; int num56 = (nbCompressedBytes * 8 << 3) - (int)enc.tell_frac() - 1; int num57 = ((num2 != 0 && i >= 2 && num56 >= i + 2 << 3) ? 8 : 0); num56 -= num57; int signalBandwidth = num12 - 1; if (analysis.valid != 0) { int b = ((num10 < 32000 * num4) ? 13 : ((num10 < 48000 * num4) ? 16 : ((num10 < 60000 * num4) ? 18 : ((num10 >= 80000 * num4) ? 20 : 19)))); signalBandwidth = Inlines.IMAX(analysis.bandwidth, b); } if (lfe != 0) { signalBandwidth = 1; } int balance; int num58 = Rate.compute_allocation_encode(celtMode, num11, num12, array9, array10, num50, ref intensity, ref dual_stereo, num56, out balance, pulses, array11, fine_priority, num4, i, enc, compressed.Slice(compressed_ptr), lastCodedBands, signalBandwidth); if (lastCodedBands != 0) { lastCodedBands = Inlines.IMIN(lastCodedBands + 1, Inlines.IMAX(lastCodedBands - 1, num58)); } else { lastCodedBands = num58; } QuantizeBands.quant_fine_energy(celtMode, num11, num12, oldBandE, error, array11, enc, compressed.Slice(compressed_ptr), num4); byte[] collapse_masks = new byte[num4 * nbEBands]; Bands.quant_all_bands_encode(1, celtMode, num11, num12, array7[0], (num4 == 2) ? array7[1] : null, collapse_masks, array3, pulses, num, spread_decision, dual_stereo, intensity, array8, nbCompressedBytes * 64 - num57, balance, enc, compressed.Slice(compressed_ptr), i, num58, ref rng); if (num57 > 0) { num6 = ((consec_transient < 2) ? 1 : 0); enc.enc_bits(compressed.Slice(compressed_ptr), (uint)num6, 1u); } QuantizeBands.quant_energy_finalise(celtMode, num11, num12, oldBandE, error, array11, fine_priority, nbCompressedBytes * 8 - enc.tell(), enc, compressed.Slice(compressed_ptr), num4); if (num7 != 0) { for (int j = 0; j < nbEBands; j++) { oldBandE[0][j] = -28672; } if (num4 == 2) { for (int j = 0; j < nbEBands; j++) { oldBandE[1][j] = -28672; } } } prefilter_period = pitch; prefilter_gain = gain; prefilter_tapset = num5; if (num3 == 2 && num4 == 1) { Arrays.MemCopy(oldBandE[0], 0, oldBandE[1], 0, nbEBands); } if (num2 == 0) { Arrays.MemCopy(oldLogE[0], 0, oldLogE2[0], 0, nbEBands); Arrays.MemCopy(oldBandE[0], 0, oldLogE[0], 0, nbEBands); if (num3 == 2) { Arrays.MemCopy(oldLogE[1], 0, oldLogE2[1], 0, nbEBands); Arrays.MemCopy(oldBandE[1], 0, oldLogE[1], 0, nbEBands); } } else { for (int j = 0; j < nbEBands; j++) { oldLogE[0][j] = Inlines.MIN16(oldLogE[0][j], oldBandE[0][j]); } if (num3 == 2) { for (int j = 0; j < nbEBands; j++) { oldLogE[1][j] = Inlines.MIN16(oldLogE[1][j], oldBandE[1][j]); } } } num26 = 0; do { for (int j = 0; j < num11; j++) { oldBandE[num26][j] = 0; oldLogE[num26][j] = (oldLogE2[num26][j] = -28672); } for (int j = num12; j < nbEBands; j++) { oldBandE[num26][j] = 0; oldLogE[num26][j] = (oldLogE2[num26][j] = -28672); } } while (++num26 < num3); if (num2 != 0 || num8 != 0) { consec_transient++; } else { consec_transient = 0; } rng = enc.rng; enc.enc_done(compressed.Slice(compressed_ptr)); if (enc.get_error() != 0) { return -3; } return nbCompressedBytes; } internal void SetComplexity(int value) { if (value < 0 || value > 10) { throw new ArgumentException("Complexity must be between 0 and 10 inclusive"); } complexity = value; } internal void SetStartBand(int value) { if (value < 0 || value >= mode.nbEBands) { throw new ArgumentException("Start band above max number of ebands (or negative)"); } start = value; } internal void SetEndBand(int value) { if (value < 1 || value > mode.nbEBands) { throw new ArgumentException("End band above max number of ebands (or less than 1)"); } end = value; } internal void SetPacketLossPercent(int value) { if (value < 0 || value > 100) { throw new ArgumentException("Packet loss must be between 0 and 100"); } loss_rate = value; } internal void SetPrediction(int value) { if (value < 0 || value > 2) { throw new ArgumentException("CELT prediction mode must be 0, 1, or 2"); } disable_pf = ((value <= 1) ? 1 : 0); force_intra = ((value == 0) ? 1 : 0); } internal void SetVBRConstraint(bool value) { constrained_vbr = (value ? 1 : 0); } internal void SetVBR(bool value) { vbr = (value ? 1 : 0); } internal void SetBitrate(int value) { if (value <= 500 && value != -1) { throw new ArgumentException("Bitrate out of range"); } value = Inlines.IMIN(value, 260000 * channels); bitrate = value; } internal void SetChannels(int value) { if (value < 1 || value > 2) { throw new ArgumentException("Channel count must be 1 or 2"); } stream_channels = value; } internal void SetLSBDepth(int value) { if (value < 8 || value > 24) { throw new ArgumentException("Bit depth must be between 8 and 24"); } lsb_depth = value; } internal int GetLSBDepth() { return lsb_depth; } internal void SetExpertFrameDuration(OpusFramesize value) { variable_duration = value; } internal void SetSignalling(int value) { signalling = value; } internal void SetAnalysis(AnalysisInfo value) { if (value == null) { throw new ArgumentNullException("AnalysisInfo"); } analysis.Assign(value); } internal CeltMode GetMode() { return mode; } internal uint GetFinalRange() { return rng; } internal void SetLFE(int value) { lfe = value; } internal void SetEnergyMask(int[] value) { energy_mask = value; } } internal class CeltMode { internal int Fs; internal int overlap; internal int nbEBands; internal int effEBands; internal int[] preemph = new int[4]; internal short[] eBands; internal int maxLM; internal int nbShortMdcts; internal int shortMdctSize; internal int nbAllocVectors; internal byte[] allocVectors; internal short[] logN; internal int[] window; internal MDCTLookup mdct = new MDCTLookup(); internal PulseCache cache = new PulseCache(); internal static readonly CeltMode mode48000_960_120 = new CeltMode { Fs = 48000, overlap = 120, nbEBands = 21, effEBands = 21, preemph = new int[4] { 27853, 0, 4096, 8192 }, eBands = Tables.eband5ms, maxLM = 3, nbShortMdcts = 8, shortMdctSize = 120, nbAllocVectors = 11, allocVectors = Tables.band_allocation, logN = Tables.logN400, window = Tables.window120, mdct = new MDCTLookup { n = 1920, maxshift = 3, kfft = new FFTState[4] { Tables.fft_state48000_960_0, Tables.fft_state48000_960_1, Tables.fft_state48000_960_2, Tables.fft_state48000_960_3 }, trig = Tables.mdct_twiddles960 }, cache = new PulseCache { size = 392, index = Tables.cache_index50, bits = Tables.cache_bits50, caps = Tables.cache_caps50 } }; private CeltMode() { } } internal class FFTState { internal int nfft; internal short scale; internal int scale_shift; internal int shift; internal short[] factors = new short[16]; internal short[] bitrev; internal short[] twiddles; } internal class MDCTLookup { internal int n; internal int maxshift; internal FFTState[] kfft = new FFTState[4]; internal short[] trig; internal MDCTLookup() { } } internal class PulseCache { internal int size; internal short[] index; internal byte[] bits; internal byte[] caps; internal void Reset() { size = 0; index = null; bits = null; caps = null; } } } namespace Concentus.Celt.Enums { internal static class Spread { internal const int SPREAD_NONE = 0; internal const int SPREAD_LIGHT = 1; internal const int SPREAD_NORMAL = 2; internal const int SPREAD_AGGRESSIVE = 3; } } [CompilerGenerated] internal sealed class { [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 3)] internal struct __StaticArrayInitTypeSize=3 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 5)] internal struct __StaticArrayInitTypeSize=5 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 6)] internal struct __StaticArrayInitTypeSize=6 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 7)] internal struct __StaticArrayInitTypeSize=7 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 9)] internal struct __StaticArrayInitTypeSize=9 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 10)] internal struct __StaticArrayInitTypeSize=10 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 11)] internal struct __StaticArrayInitTypeSize=11 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 12)] internal struct __StaticArrayInitTypeSize=12 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 15)] internal struct __StaticArrayInitTypeSize=15 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 16)] internal struct __StaticArrayInitTypeSize=16 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 17)] internal struct __StaticArrayInitTypeSize=17 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 18)] internal struct __StaticArrayInitTypeSize=18 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 21)] internal struct __StaticArrayInitTypeSize=21 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 22)] internal struct __StaticArrayInitTypeSize=22 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 24)] internal struct __StaticArrayInitTypeSize=24 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 25)] internal struct __StaticArrayInitTypeSize=25 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 28)] internal struct __StaticArrayInitTypeSize=28 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 30)] internal struct __StaticArrayInitTypeSize=30 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 32)] internal struct __StaticArrayInitTypeSize=32 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 34)] internal struct __StaticArrayInitTypeSize=34 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 40)] internal struct __StaticArrayInitTypeSize=40 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 41)] internal struct __StaticArrayInitTypeSize=41 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 42)] internal struct __StaticArrayInitTypeSize=42 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 44)] internal struct __StaticArrayInitTypeSize=44 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 54)] internal struct __StaticArrayInitTypeSize=54 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 58)] internal struct __StaticArrayInitTypeSize=58 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)] internal struct __StaticArrayInitTypeSize=60 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 64)] internal struct __StaticArrayInitTypeSize=64 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 68)] internal struct __StaticArrayInitTypeSize=68 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 72)] internal struct __StaticArrayInitTypeSize=72 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 76)] internal struct __StaticArrayInitTypeSize=76 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 84)] internal struct __StaticArrayInitTypeSize=84 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 88)] internal struct __StaticArrayInitTypeSize=88 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 96)] internal struct __StaticArrayInitTypeSize=96 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 120)] internal struct __StaticArrayInitTypeSize=120 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 128)] internal struct __StaticArrayInitTypeSize=128 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 152)] internal struct __StaticArrayInitTypeSize=152 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 160)] internal struct __StaticArrayInitTypeSize=160 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 168)] internal struct __StaticArrayInitTypeSize=168 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 210)] internal struct __StaticArrayInitTypeSize=210 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 231)] internal struct __StaticArrayInitTypeSize=231 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 240)] internal struct __StaticArrayInitTypeSize=240 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 256)] internal struct __StaticArrayInitTypeSize=256 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 258)] internal struct __StaticArrayInitTypeSize=258 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 288)] internal struct __StaticArrayInitTypeSize=288 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 320)] internal struct __StaticArrayInitTypeSize=320 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 392)] internal struct __StaticArrayInitTypeSize=392 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 480)] internal struct __StaticArrayInitTypeSize=480 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 512)] internal struct __StaticArrayInitTypeSize=512 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 544)] internal struct __StaticArrayInitTypeSize=544 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 804)] internal struct __StaticArrayInitTypeSize=804 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 960)] internal struct __StaticArrayInitTypeSize=960 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 1688)] internal struct __StaticArrayInitTypeSize=1688 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 1920)] internal struct __StaticArrayInitTypeSize=1920 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 3600)] internal struct __StaticArrayInitTypeSize=3600 { } [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 5088)] internal struct __StaticArrayInitTypeSize=5088 { } internal static readonly __StaticArrayInitTypeSize=24 003F97BBC6D0FDBE9807A0380621418B2323DCABC7CA5410DBFFDBE94D69E1B8/* Not supported: data(00 08 0D 10 13 15 17 18 1A 1B 1C 1D 1E 1F 20 20 21 22 22 23 24 24 25 25) */; internal static readonly __StaticArrayInitTypeSize=24 0047592A770195B6309532002BC85FD35942458FCC90735AAA7F5CEDCF3825C8/* Not supported: data(00 40 00 00 6C 22 00 00 42 0F 00 00 12 06 00 00 4D 02 00 00 DB 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 011F2B41404D4DD11D5B097683B2623598B4AA4506DC4B6E948C72A5FADDCF26/* Not supported: data(08 ED 66 2E F3) */; internal static readonly __StaticArrayInitTypeSize=18 020DF106160933F38609AD311539032ECB6EBE7DAC42DBB4ABAB2E688E9C11B5/* Not supported: data(C6 69 2D 16 0F 0C 0B 0A 09 08 07 06 05 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=160 025106732C88A3642E3B46B01F41B948AC01B380053A08C7C4438DDF09CECCE3/* Not supported: data(10 00 00 00 00 63 42 24 24 22 24 22 22 22 22 53 45 24 34 22 74 66 46 44 44 B0 66 44 44 22 41 55 44 54 24 74 8D 98 8B AA 84 BB B8 D8 89 84 F9 A8 B9 8B 68 66 64 44 44 B2 DA B9 B9 AA F4 D8 BB BB AA F4 BB BB DB 8A 67 9B B8 B9 89 74 B7 9B 98 88 84 D9 B8 B8 AA A4 D9 AB 9B 8B F4 A9 B8 B9 AA A4 D8 DF DA 8A D6 8F BC DA A8 F4 8D 88 9B AA A8 8A DC DB 8B A4 DB CA D8 89 A8 BA F6 B9 8B 74 B9 DB B9 8A 64 64 86 64 66 22 44 44 64 44 A8 CB DD DA A8 A7 9A 88 68 46 A4 F6 AB 89 8B 89 9B DA DB 8B) */; internal static readonly __StaticArrayInitTypeSize=64 026BC40D81B8ED39403BD008805CF80B059A2CDC532F021A026EE2B25230F13F/* Not supported: data(D4 B2 94 81 6C 60 55 52 4F 4D 3D 3B 39 38 33 31 30 2D 2A 29 28 26 24 22 1F 1E 15 0C 0A 03 01 00 FF F5 F4 EC E9 E1 D9 CB BE B0 AF A1 95 88 7D 72 66 5B 51 47 3C 34 2B 23 1C 14 13 12 0C 0B 05 00) */; internal static readonly __StaticArrayInitTypeSize=42 05120350D330EB951DC9A46A4DFF6D5A213FB390B53F84EE546A1E6DAAB016DE/* Not supported: data(15 B2 3B 6E 47 56 4B 55 54 53 5B 42 58 49 57 48 5C 4B 62 48 69 3A 6B 36 73 34 72 37 70 38 81 33 84 28 96 21 8C 1D 62 23 4D 2A) */; internal static readonly int 054EDEC1D0211F624FED0CBCA9D4F9400B0E491C43742AF2C5B0ABEBF0C990D8/* Not supported: data(00 01 02 03) */; internal static readonly __StaticArrayInitTypeSize=5 06AB12DABBF679B8DC0F9E423F37F4F638D3E52717593438C0A6F68450ACAD94/* Not supported: data(03 02 0D 03 02) */; internal static readonly __StaticArrayInitTypeSize=5 081342C77E8E7CA742BF7D076856B9ED5AB85D01AD54ACCDE13C799762A3DD97/* Not supported: data(00 04 01 02 03) */; internal static readonly __StaticArrayInitTypeSize=960 08B8CAF8F78D4BD7FD969880024733234564B34DED03965D3F1D7051A421D49E/* Not supported: data(E6 5A 34 38 77 4E 33 39 D3 D9 C9 39 92 91 33 3A CC 60 8C 3A 61 FB C9 3A 99 7E 09 3B CB 80 33 3B D5 25 63 3B 77 2E 8C 3B A8 8A A9 3B 45 B8 C9 3B 87 A6 EC 3B E8 2E 09 3C AE 66 1D 3C F7 02 33 3C 93 FF 49 3C 4F 58 62 3C 5E 11 7C 3C 2E 91 8B 3C BD C7 99 3C 5C AC A8 3C F3 3C B8 3C 81 79 C8 3C EE 5F D9 3C 39 F0 EA 3C 63 2A FD 3C 35 07 08 3D 10 CC 11 3D CD E4 1B 3D 61 50 26 3D CB 0E 31 3D 00 1F 3C 3D FE 80 47 3D C6 34 53 3D 3F 38 5F 3D 69 8B 6B 3D 45 2E 78 3D 69 90 82 3D 7B 30 89 3D E0 F7 8F 3D 8A E5 96 3D 7B F9 9D 3D B1 33 A5 3D 21 93 AC 3D 50 18 B4 3D 33 C2 BB 3D 4F 91 C3 3D 12 84 CB 3D 02 9B D3 3D 1F D6 DB 3D D7 33 E4 3D AF B4 EC 3D 21 58 F5 3D A8 1D FE 3D A1 82 03 3E F2 06 08 3E C7 9B 0C 3E DD 40 11 3E 34 F6 15 3E 45 BB 1A 3E 11 90 1F 3E 54 74 24 3E CB 67 29 3E 33 6A 2E 3E 8D 7B 33 3E 52 9B 38 3E C5 C9 3D 3E 1C 06 43 3E 59 50 48 3E 7A A8 4D 3E B7 0D 53 3E 52 80 58 3E 08 00 5E 3E 54 8C 63 3E F2 24 69 3E 25 CA 6E 3E 24 7B 74 3E AC 37 7A 3E 00 00 80 3E AB E9 82 3E F9 D8 85 3E 85 CD 88 3E 50 C7 8B 3E 37 C6 8E 3E F7 C9 91 3E B3 D2 94 3E 26 E0 97 3E 0F F2 9A 3E 6C 08 9E 3E 1C 23 A1 3E FF 41 A4 3E D0 64 A7 3E B1 8B AA 3E 1C B6 AD 3E 54 E4 B0 3E D3 15 B4 3E BA 4A B7 3E E8 82 BA 3E F9 BD BD 3E 0D FC C0 3E E2 3C C4 3E 56 80 C7 3E 47 C6 CA 3E 95 0E CE 3E FB 58 D1 3E 7A A5 D4 3E F1 F3 D7 3E 1C 44 DB 3E D9 95 DE 3E 08 E9 E1 3E A7 3D E5 3E 53 93 E8 3E 0C EA EB 3E AF 41 EF 3E 1C 9A F2 3E 0E F3 F5 3E 88 4C F9 3E 22 A6 FC 3E 00 00 00 3F EF AC 01 3F BC 59 03 3F 79 06 05 3F F2 B2 06 3F 29 5F 08 3F FA 0A 0A 3F 56 B6 0B 3F 2C 61 0D 3F 7C 0B 0F 3F 13 B5 10 3F F2 5D 12 3F 08 06 14 3F 43 AD 15 3F 82 53 17 3F B6 F8 18 3F DC 9C 1A 3F D5 3F 1C 3F 8F E1 1D 3F F9 81 1F 3F 04 21 21 3F 8C BE 22 3F A3 5A 24 3F 17 F5 25 3F D6 8D 27 3F F2 24 29 3F 28 BA 2A 3F 98 4D 2C 3F 01 DF 2D 3F 72 6E 2F 3F CA FB 30 3F F9 86 32 3F ED 0F 34 3F A7 96 35 3F 04 1B 37 3F E5 9C 38 3F 58 1C 3A 3F 3D 99 3B 3F 83 13 3D 3F 2A 8B 3E 3F 00 00 40 3F 15 72 41 3F 37 E1 42 3F 77 4D 44 3F C3 B6 45 3F EB 1C 47 3F FE 7F 48 3F EC DF 49 3F 92 3C 4B 3F E1 95 4C 3F EA EB 4D 3F 79 3E 4F 3F 8F 8D 50 3F 2B D9 51 3F 1D 21 53 3F 73 65 54 3F 0D A6 55 3F EB E2 56 3F FC 1B 58 3F 2F 51 59 3F 73 82 5A 3F C9 AF 5B 3F 0E D9 5C 3F 43 FE 5D 3F 58 1F 5F 3F 4B 3C 60 3F FC 54 61 3F 6A 69 62 3F 85 79 63 3F 3C 85 64 3F A0 8C 65 3F 7E 8F 66 3F D6 8D 67 3F BA 87 68 3F F6 7C 69 3F 9C 6D 6A 3F 8A 59 6B 3F D1 40 6C 3F 4F 23 6D 3F 04 01 6E 3F F1 D9 6E 3F F3 AD 6F 3F 1C 7D 70 3F 49 47 71 3F 7C 0C 72 3F B4 CC 72 3F F0 87 73 3F 10 3E 74 3F 13 EF 74 3F FA 9A 75 3F B3 41 76 3F 3F E3 76 3F 8D 7F 77 3F AD 16 78 3F 7E A8 78 3F 01 35 79 3F 34 BC 79 3F 18 3E 7A 3F 9D BA 7A 3F C2 31 7B 3F 77 A3 7B 3F BB 0F 7C 3F 9F 76 7C 3F 02 D8 7C 3F F4 33 7D 3F 65 8A 7D 3F 44 DB 7D 3F B3 26 7E 3F 8F 6C 7E 3F EB AC 7E 3F A3 E7 7E 3F DA 1C 7F 3F 7F 4C 7F 3F 81 76 7F 3F 02 9B 7F 3F D0 B9 7F 3F 1C D3 7F 3F C5 E6 7F 3F CB F4 7F 3F 2F FD 7F 3F 00 00 80 3F) */; internal static readonly __StaticArrayInitTypeSize=11 09316A7E053C5A5BB6D6D16A58426B0F3B45E4BD17593BE316C12F16BA3127BE/* Not supported: data(BC B0 9B 8A 77 61 43 2B 1A 0A 00) */; internal static readonly __StaticArrayInitTypeSize=5 0955922D7998827FDD609328E029F84160E02E09F516C1E0E3880DCB18841AA5/* Not supported: data(FE 37 2E FE 0F) */; internal static readonly __StaticArrayInitTypeSize=34 0A5164B2EF17D74636FDE2D0E997F70443BAD032D00D148ED5CDE1785E2ED241/* Not supported: data(DF C9 B7 A7 98 8A 7C 6F 62 58 4F 46 3E 38 32 2C 27 23 1F 1B 18 15 12 10 0E 0C 0A 08 06 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=18 0B3EF69B7E9E90C95C4C9B4A896389CDF2B34898CB9AB0D30F9A32D314C68C0D/* Not supported: data(A6 86 71 66 65 66 6B 76 7D 8A 91 9B A6 B6 C0 C0 CD 96) */; internal static readonly __StaticArrayInitTypeSize=18 0C08B0444C57396E19823D689E98FC8DE10167828046FD9F9B12DFDF155515E5/* Not supported: data(FF FE FD F7 DC A2 6A 43 2A 1C 12 0C 09 06 04 03 02 00) */; internal static readonly __StaticArrayInitTypeSize=42 0C2C8407304B295EA131924A851F799D05F1415040E99817E74BD01128A9ACC0/* Not supported: data(17 B2 36 73 3F 66 42 62 45 63 4A 59 47 5B 49 5B 4E 59 56 50 5C 42 5D 40 66 3B 67 3C 68 3C 75 34 7B 2C 8A 23 85 1F 61 26 4D 2D) */; internal static readonly __StaticArrayInitTypeSize=18 0DDA873A004F196A7C9796DB0D3145C286E0CEB71C2F626125C4A2707B099B9F/* Not supported: data(1F 39 6B A0 CD CD FF FF FF FF FF FF FF FF FF FF FF FF) */; internal static readonly __StaticArrayInitTypeSize=5 0ECEF16DA982EF4AE2B0CC2A5FA323B1E4F14422FB2C9A92EFCA38F6EDFDE8E5/* Not supported: data(F6 25 41 FC 03) */; internal static readonly __StaticArrayInitTypeSize=804 1018EF0D5BB6CBC5F06430E106B5C39EDA8DE0ABFAACDED01D092A02BBC7BF8F/* Not supported: data(00 00 00 00 05 C1 23 3D E9 7D A3 3D 25 96 F4 3D E2 74 22 3E AC 1C 4A 3E DD 25 71 3E 34 BA 8B 3E B4 77 9E 3E E4 BF B0 3E AD 88 C2 3E 25 C9 D3 3E 18 7A E4 3E 18 95 F4 3E C8 0A 02 3F 1C 7C 09 3F 49 9D 10 3F CA 6D 17 3F C0 ED 1D 3F 9F 1D 24 3F 54 FE 29 3F 2E 91 2F 3F E0 D7 34 3F 63 D4 39 3F F0 88 3E 3F D3 F7 42 3F AB 23 47 3F 17 0F 4B 3F D8 BC 4E 3F AD 2F 52 3F 6A 6A 55 3F CE 6F 58 3F 9A 42 5B 3F 8E E5 5D 3F 4B 5B 60 3F 6E A6 62 3F 64 C9 64 3F 9B C6 66 3F 6F A0 68 3F F7 58 6A 3F 80 F2 6B 3F DF 6E 6D 3F 0B D0 6E 3F CA 17 70 3F E0 47 71 3F E1 61 72 3F 4D 67 73 3F 96 59 74 3F 0C 3A 75 3F FF 09 76 3F 8A CA 76 3F BB 7C 77 3F C0 21 78 3F 62 BA 78 3F 9D 47 79 3F 4B CA 79 3F 24 43 7A 3F F2 B2 7A 3F 3B 1A 7B 3F C8 79 7B 3F 20 D2 7B 3F C8 23 7C 3F 37 6F 7C 3F F2 B4 7C 3F 5E F5 7C 3F E0 30 7D 3F EC 67 7D 3F B7 9A 7D 3F B4 C9 7D 3F 06 F5 7D 3F 11 1D 7E 3F 18 42 7E 3F 4E 64 7E 3F D3 83 7E 3F FD A0 7E 3F ED BB 7E 3F C3 D4 7E 3F B3 EB 7E 3F EF 00 7F 3F 87 14 7F 3F 8D 26 7F 3F 43 37 7F 3F AA 46 7F 3F E3 54 7F 3F 0F 62 7F 3F 2F 6E 7F 3F 64 79 7F 3F BE 83 7F 3F 3F 8D 7F 3F 18 96 7F 3F 38 9E 7F 3F C2 A5 7F 3F A3 AC 7F 3F 10 B3 7F 3F F5 B8 7F 3F 77 BE 7F 3F 72 C3 7F 3F 19 C8 7F 3F 6C CC 7F 3F 5B D0 7F 3F 06 D4 7F 3F 6F D7 7F 3F 83 DA 7F 3F 66 DD 7F 3F 15 E0 7F 3F 82 E2 7F 3F CD E4 7F 3F E6 E6 7F 3F CD E8 7F 3F 92 EA 7F 3F 46 EC 7F 3F C8 ED 7F 3F 28 EF 7F 3F 78 F0 7F 3F A6 F1 7F 3F C3 F2 7F 3F BF F3 7F 3F BA F4 7F 3F 94 F5 7F 3F 5E F6 7F 3F 27 F7 7F 3F CF F7 7F 3F 77 F8 7F 3F FD F8 7F 3F 94 F9 7F 3F 09 FA 7F 3F 7F FA 7F 3F F4 FA 7F 3F 59 FB 7F 3F AD FB 7F 3F 01 FC 7F 3F 54 FC 7F 3F 98 FC 7F 3F DB FC 7F 3F 1E FD 7F 3F 50 FD 7F 3F 82 FD 7F 3F B5 FD 7F 3F E7 FD 7F 3F 09 FE 7F 3F 3B FE 7F 3F 5D FE 7F 3F 7E FE 7F 3F 8F FE 7F 3F B0 FE 7F 3F D2 FE 7F 3F E3 FE 7F 3F F4 FE 7F 3F 15 FF 7F 3F 26 FF 7F 3F 37 FF 7F 3F 47 FF 7F 3F 58 FF 7F 3F 58 FF 7F 3F 69 FF 7F 3F 7A FF 7F 3F 7A FF 7F 3F 8B FF 7F 3F 9B FF 7F 3F 9B FF 7F 3F 9B FF 7F 3F AC FF 7F 3F AC FF 7F 3F BD FF 7F 3F BD FF 7F 3F BD FF 7F 3F CE FF 7F 3F CE FF 7F 3F CE FF 7F 3F CE FF 7F 3F CE FF 7F 3F DE FF 7F 3F DE FF 7F 3F DE FF 7F 3F DE FF 7F 3F DE FF 7F 3F DE FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F EF FF 7F 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F 00 00 80 3F) */; internal static readonly __StaticArrayInitTypeSize=288 10238142CCB8C135674FFEC112A79F947F3A30B96A76DE2F807B9FF75DB2F5A2/* Not supported: data(25 91 E0 BA 20 EA EF 3F 00 00 00 00 00 00 F0 3F 25 91 E0 BA 20 EA EF 3F DE 4B 2B CF CD A8 EF 3F 5A 1F FF 9A E6 3C EF 3F 55 CF 17 B5 DA A7 EE 3F BE A0 64 F6 A2 EB ED 3F D7 90 6E 3A B8 0A ED 3F 8B E8 CF 65 07 08 EC 3F B5 DE 6F B4 E3 E6 EA 3F 58 00 74 14 F7 AA E9 3F 22 72 55 34 31 58 E8 3F 50 C5 AE 69 B5 F2 E6 3F 58 E4 B6 01 C8 7E E5 3F 94 45 27 6C BB 00 E4 3F 47 2B 4A 4B DD 7C E2 3F A9 A3 E3 6A 64 F7 E0 3F AA A9 97 A5 BE E8 DE 3F 16 C4 7A 82 48 EF DB 3F 4B 66 CC 8F 85 09 D9 3F 3F E9 E1 57 EE 3D D6 3F C2 6A 6E 7D 3F 92 D3 3F A0 BE A7 6A 69 0B D1 3F 2B 72 5F 39 08 5B CD 3F 27 99 62 2F 90 F7 C8 3F A1 07 CA AF 17 F1 C4 3F CA 62 AC 80 8C 4A C1 3F 22 C5 BE 6C 54 0A BC 3F 61 85 00 85 1F 41 B6 3F 8F DE 70 1F B9 35 B1 3F 43 84 C9 9E 4E C3 A9 3F 21 7B 7B DF 11 78 A2 3F F3 47 28 E8 BC E7 98 3F 59 ED 0E E7 E9 75 8E 3F 21 02 0E A1 4A CD 7E 3F 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=32 11878BBA60FD7D96DEB6848ECDB9CE522445A94B083AE8C884E9BC21512F1C97/* Not supported: data(00 00 00 00 04 29 00 00 B0 36 00 00 68 42 00 00 FC 53 00 00 54 6F 00 00 10 A4 00 00 80 38 01 00) */; internal static readonly __StaticArrayInitTypeSize=18 136BD813016FD90AA653A3EE3CC8B1A49A6EC8B90FE52897D6E8862BA88B464F/* Not supported: data(FF FD F9 EF DC BF 9C 77 55 39 25 17 0F 0A 06 04 02 00) */; internal static readonly __StaticArrayInitTypeSize=6 145C0EBAB42AF4F6DEA72812A958DBEF2CFA5C90E13C6C9576C62428E1B4852A/* Not supported: data(00 04 01 02 03 05) */; internal static readonly __StaticArrayInitTypeSize=5 14F6F4E6BF5E8B821769BF91AC91105F0AF49565185BB5E3380D41CDF10CBF2A/* Not supported: data(09 EB 54 48 EE) */; internal static readonly __StaticArrayInitTypeSize=5 178939D8F8D24170CC83896C269B4383FB613CD269BB4377FE2E5145E58DB939/* Not supported: data(FA 1B 3D 27 05) */; internal static readonly __StaticArrayInitTypeSize=16 197E2E159C2B4F0C33BB3AC7DE6628DEB2B418EAECAA8F882AA0B8AF91A21E02/* Not supported: data(C3 75 00 00 0A 57 00 00 5C 2F 00 00 9A 19 00 00) */; internal static readonly __StaticArrayInitTypeSize=42 19A834A3A24D4B5A6258F28EB310D562B82A35E9F41CA596818447B62D763162/* Not supported: data(2A 79 60 42 6C 2B 6F 28 75 2C 7B 20 78 24 77 21 7F 21 86 22 8B 15 93 17 98 14 9E 19 9A 1A A6 15 AD 10 B8 0D B8 0A 96 0D 8B 0F) */; internal static readonly __StaticArrayInitTypeSize=16 1AADCB2BE9AFB838C1D1652C6D21F5E4A30F335976E5135BFD1F3EA71FBB6A47/* Not supported: data(12 00 1D 00 26 00 28 00 2E 00 34 00 3E 00 54 00) */; internal static readonly __StaticArrayInitTypeSize=11 1BB17C82856D43453B9A834965F0987E1FFAC58A16FD4B4E8F389C15A8103F59/* Not supported: data(7E 7C 77 6D 57 29 13 09 04 02 00) */; internal static readonly __StaticArrayInitTypeSize=5 1CD1FD6D63BCFA716C4F353714AB96FB22A787BF298B5231C3B4A93685A6498A/* Not supported: data(05 F7 2C 5C F8) */; internal static readonly __StaticArrayInitTypeSize=84 1D9E4E326D4F24B82D5CBB4DFC33EDC24715E0FF1DE469EB885E6764D58BD1EE/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 10 00 00 00 18 00 00 00 24 00 00 00 2C 00 00 00 32 00 00 00 38 00 00 00 3E 00 00 00 43 00 00 00 48 00 00 00 4F 00 00 00 58 00 00 00 6A 00 00 00 86 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=72 1F38DB61B16E929F6597543F9F331653148C3F22B1CD457ED948E6C50DA4B668/* Not supported: data(FF FE FD F4 0C 03 02 01 00 FF FE FC E0 26 03 02 01 00 FF FE FB D1 39 04 02 01 00 FF FE F4 C3 45 04 02 01 00 FF FB E8 B8 54 07 02 01 00 FF FE F0 BA 56 0E 02 01 00 FF FE EF B2 5B 1E 05 01 00 FF F8 E3 B1 64 13 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=18 1FB4BF50DEA351C5B1540D80D5692518AD1336AEF7EB31F9EDFCDA3912C53AD7/* Not supported: data(FF FD FB F6 ED DF CB B3 98 7C 62 4B 37 28 1D 15 0F 00) */; internal static readonly __StaticArrayInitTypeSize=128 22853AE05777B5B1BDB8509643D8564C4C8BE849272DC3A36F15380D11E44384/* Not supported: data(FF FF 9C 6E 56 46 3B 33 2D 28 25 21 1F 1C 1A 19 17 16 15 14 13 12 11 10 10 0F 0F 0E 0D 0D 0C 0C 0C 0C 0B 0B 0B 0A 0A 0A 09 09 09 09 09 09 08 08 08 08 08 07 07 07 07 07 07 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 05 05 05 05 05 05 05 05 05 05 05 05 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 02) */; internal static readonly __StaticArrayInitTypeSize=68 25BBF084C605DCC4E1C748B58D8F8428074DBD46F3359502521CA213EA7F4AAD/* Not supported: data(00 02 00 00 2C 01 00 00 A5 00 00 00 57 00 00 00 2D 00 00 00 17 00 00 00 0B 00 00 00 06 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 266991C2409701F4228210CF3943CC63785A9751532EBC950F3AA787C6188F83/* Not supported: data(FA 17 75 F4 03) */; internal static readonly __StaticArrayInitTypeSize=5 276F14C233EFDA4838AB3CA909588635BEA860C684EC3366D626998BE12F64E0/* Not supported: data(01 FE 3E 29 F7) */; internal static readonly __StaticArrayInitTypeSize=5 28FB1971058461D7691844081ACA5DC3C1A2C78897C6E3EACBE4119179C4FA2A/* Not supported: data(1A 27 3B 03 F8) */; internal static readonly __StaticArrayInitTypeSize=5 29CC59B5398F119C057C8D70E0DD31A77677AA8B3706EAC9F2BB791B5A646B37/* Not supported: data(0C 1C 29 0D FC) */; internal static readonly __StaticArrayInitTypeSize=10 2BC27B1E5732948818AABD0D833569AC2915CAE5A57FB21845E44C3C56D1EBCE/* Not supported: data(87 5A 29 2D 3D F4 A3 06 68 FD) */; internal static readonly __StaticArrayInitTypeSize=5 2CA5F4106DB14A5476E93CC409EDDD2F0C47EEA432D8FDBD78518A701D47E3B9/* Not supported: data(06 F5 4A 35 F7) */; internal static readonly __StaticArrayInitTypeSize=5 2E7BFD902FE03003E0DBDD1F4D69DF7AC98E4658B1217B879EB8666CD6F592F4/* Not supported: data(10 0E 26 FD 21) */; internal static readonly __StaticArrayInitTypeSize=32 2F2E64F4CE7C574C62B3D244B038E83C9C9405DA6E13B0E83A46DC20000D67C1/* Not supported: data(7E 7C 7D 7C 81 79 7E 17 84 7F 7F 7F 7E 7F 7A 85 82 86 65 76 77 91 7E 56 7C 78 7B 77 AA AD 6B 6D) */; internal static readonly __StaticArrayInitTypeSize=42 3139CB25812D4FECE875DCD73CBD780F5C85FF6F9E557A8B4501EC3C0039AC72/* Not supported: data(16 B2 3F 72 4A 52 54 53 5C 52 67 3E 60 48 60 43 65 49 6B 48 71 37 76 34 7D 34 76 34 75 37 87 31 89 27 9D 20 91 1D 61 21 4D 28) */; internal static readonly __StaticArrayInitTypeSize=12 31F4AF5F1DFCA654494967ADFB8F512F3676623530E56E9A4CABEE4DDF56280F/* Not supported: data(DA 02 D7 07 F9 C6 AD 0F DA 02 D7 07) */; internal static readonly __StaticArrayInitTypeSize=32 33ADB042ECC6C15A523FB6679A3C5CA61B1691D1F0368D62302285443DF89A6E/* Not supported: data(83 80 86 8D 8D 8D 91 91 91 96 9B 9B 9B 9B A0 A0 A0 A0 A6 A6 AD AD B6 C0 B6 C0 C0 C0 CD C0 CD E0) */; internal static readonly __StaticArrayInitTypeSize=16 3443534250F719826764F7520324F12BAB5E4C8C018BBBF0DB8B1C552B01E14A/* Not supported: data(45 5D 73 76 83 8A 8D 8A 96 96 9B 96 9B A0 A6 A0) */; internal static readonly __StaticArrayInitTypeSize=5 3487F87FFC2B378CE095ED45EA6B435B32250A4AE50686C567E67E7B48118AD9/* Not supported: data(03 26 54 18 E7) */; internal static readonly __StaticArrayInitTypeSize=16 34FD5609F00BF32A4F685CA37BF6D61DD394885698C9437A7F8FA5E73BDA101F/* Not supported: data(00 03 0C 0F 30 33 3C 3F C0 C3 CC CF F0 F3 FC FF) */; internal static readonly __StaticArrayInitTypeSize=258 351CA26770B4435B16363ED5D335CA82F0D391539B5E839E9ED66B16C627BC84/* Not supported: data(00 20 FE 1F F6 1F EA 1F D8 1F C2 1F A8 1F 88 1F 62 1F 3A 1F 0A 1F D8 1E A0 1E 62 1E 22 1E DC 1D 90 1D 42 1D EE 1C 96 1C 3A 1C D8 1B 72 1B 0A 1B 9C 1A 2A 1A B4 19 3A 19 BC 18 3C 18 B6 17 2E 17 A0 16 10 16 7E 15 E8 14 4E 14 B0 13 10 13 6E 12 C8 11 1E 11 74 10 C6 0F 16 0F 64 0E AE 0D F8 0C 40 0C 84 0B C8 0A 0A 0A 4A 09 8A 08 C6 07 02 07 3E 06 78 05 B2 04 EA 03 22 03 5A 02 92 01 CA 00 00 00 36 FF 6E FE A6 FD DE FC 16 FC 4E FB 88 FA C2 F9 FE F8 3A F8 76 F7 B6 F6 F6 F5 38 F5 7C F4 C0 F3 08 F3 52 F2 9C F1 EA F0 3A F0 8C EF E2 EE 38 EE 92 ED F0 EC 50 EC B2 EB 18 EB 82 EA F0 E9 60 E9 D2 E8 4A E8 C4 E7 44 E7 C6 E6 4C E6 D6 E5 64 E5 F6 E4 8E E4 28 E4 C6 E3 6A E3 12 E3 BE E2 70 E2 24 E2 DE E1 9E E1 60 E1 28 E1 F6 E0 C6 E0 9E E0 78 E0 58 E0 3E E0 28 E0 16 E0 0A E0 02 E0 00 E0) */; internal static readonly __StaticArrayInitTypeSize=5 35FE597785F5FF723D63DCEF5037AC16DB1590728FD175A6DEB21475BB75F92D/* Not supported: data(04 06 18 07 05) */; internal static readonly __StaticArrayInitTypeSize=18 381C2D64F822A0C582239F6CC970ED37C36BAD73684B47F1BA135D69FF1DE1F4/* Not supported: data(FE F9 EB CE A4 76 4D 2E 1B 10 0A 07 05 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=5 3D460E19F58F5F146438342328403D090CADFBDE45E3EB258EF608F98F65E742/* Not supported: data(05 F5 75 16 F8) */; internal static readonly __StaticArrayInitTypeSize=42 3D66E6E74FF4E19556DE99A8657ACDF610D6162EDA5F5E6F152507693F02E64A/* Not supported: data(48 7F 41 81 42 80 41 80 40 80 3E 80 40 80 40 80 5C 4E 5C 4F 5C 4E 5A 4F 74 29 73 28 72 28 84 1A 84 1A 91 11 A1 0C B0 0A B1 0B) */; internal static readonly __StaticArrayInitTypeSize=64 3D8D64CAB4D39BA6D2544F0BE00658FE4DD53A9A5878ABF82F6E59BD7F2E8C7C/* Not supported: data(00 00 00 00 00 00 00 00 03 00 00 00 02 00 00 00 03 00 00 00 02 00 00 00 05 00 00 00 02 00 00 00 03 00 00 00 02 00 00 00 03 00 00 00 02 00 00 00 05 00 00 00 02 00 00 00 03 00 00 00 02 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=15 3E087BA67D24C704B625D06E8CB59A0B77243D8A44DDDEAA02708CCD4EA517EE/* Not supported: data(06 00 03 00 07 03 00 01 0A 00 02 06 12 0A 0C) */; internal static readonly __StaticArrayInitTypeSize=28 3E1C92262CF40E8C1F33D5B6447E53170C00631ADF1459179016679FDF67DE09/* Not supported: data(68 02 0D C8 F6 FF 27 00 3A 00 D2 FF AC FF 78 00 B8 00 C5 FE E3 FD 04 05 04 15 40 23) */; internal static readonly __StaticArrayInitTypeSize=5 3F4BFFBC64F7EF55928ED7F68E53C135F0F9CFA68E9CD66B7D9C2F71A5B78BC5/* Not supported: data(FA 04 42 07 F8) */; internal static readonly __StaticArrayInitTypeSize=9 400DD08539740C3472D4263BEA7891DCECB61ECC5D25B67E08454436AC511DEF/* Not supported: data(DF C1 9D 8C 6A 39 27 12 00) */; internal static readonly __StaticArrayInitTypeSize=32 41CE26A85CFF0A7C36A440382FB90FFD38E98DE0D9E744D961922758C90D4993/* Not supported: data(05 00 0C 00 03 00 04 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=3 41F148FD96C8327E175F10C34622D1B45626D491BD1E711423DED43267349D39/* Not supported: data(10 18 22) */; internal static readonly __StaticArrayInitTypeSize=12 4275CAD060A8BBED55C3688335AFF3032ED4962785417F25EA0902B2449C07C6/* Not supported: data(0F 00 00 00 0A 00 00 00 05 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=42 43E446AF444F0E121DABEEE63533375FB818CFC84B9327AD61899195DE14289B/* Not supported: data(18 B3 30 8A 36 87 36 84 35 86 38 85 37 84 37 84 3D 72 46 60 4A 58 4B 58 57 4A 59 42 5B 43 64 3B 6C 32 78 28 7A 25 61 2B 4E 32) */; internal static readonly __StaticArrayInitTypeSize=32 43FFBB3A7DB7DEEAA87482D4918031D88E08D2FEF973242F9C0A74A1BC9C127A/* Not supported: data(E0 2E 00 00 E8 03 00 00 50 46 00 00 D0 07 00 00 08 52 00 00 D0 07 00 00 30 75 00 00 D0 07 00 00) */; internal static readonly __StaticArrayInitTypeSize=6 4441E676FACAFB7286B713A043AA65876B4B160D8BA608D1CCC604894116CBE9/* Not supported: data(C6 1A A9 64 F6 D8) */; internal static readonly __StaticArrayInitTypeSize=152 44651DDC570840A98E3023A687485B252B83B2BB6982ED3FB0ABED902AFE3C0B/* Not supported: data(80 00 D6 2A 00 EB 80 15 00 F4 B8 48 0B 00 F8 D6 80 2A 07 00 F8 E1 AA 50 19 05 00 FB EC C6 7E 36 12 03 00 FA EE D3 9F 52 23 0F 05 00 FA E7 CB A8 80 58 35 19 06 00 FC EE D8 B9 94 6C 47 28 12 04 00 FD F3 E1 C7 A6 80 5A 39 1F 0D 03 00 FE F6 E9 D4 B7 93 6D 49 2C 17 0A 02 00 FF FA F0 DF C6 A6 80 5A 3A 21 10 06 01 00 FF FB F4 E7 D2 B5 92 6E 4B 2E 19 0C 05 01 00 FF FD F8 EE DD C4 A4 80 5C 3C 23 12 08 03 01 00 FF FD F9 F2 E5 D0 B4 92 6E 4C 30 1B 0E 07 03 01 00) */; internal static readonly __StaticArrayInitTypeSize=32 45CE231EFF074EE1A385BA1FDAD8B291D8759B96A85E1F128D3E16F29D72F764/* Not supported: data(00 00 00 00 28 23 00 00 E0 2E 00 00 A4 38 00 00 44 48 00 00 B4 5F 00 00 AC 8A 00 00 80 38 01 00) */; internal static readonly long 4668AFFA37D5369D2B2A7C1109C34CC5050F7DB56F0F0FBA98963129371B1973/* Not supported: data(FE ED C0 84 46 17 04 00) */; internal static readonly __StaticArrayInitTypeSize=42 4703B742002A0C68D0185BB6ADB52B1179AF8959388AB24C6B5E8F925FEC426D/* Not supported: data(53 4E 54 51 58 4B 56 4A 57 47 5A 49 5D 4A 5D 4A 6D 28 72 24 75 22 75 22 8F 11 91 12 92 13 A2 0C A5 0A B2 07 BD 06 BE 08 B1 09) */; internal static readonly long 4A1C706A0FED1F60D6EF34337357C9F59672A78DC27B36F6C58C01328EBCC747/* Not supported: data(E0 70 2C 0F 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=5 4BD9E5167675F14A0ABAEFB7B38AEA5C862D4CCB4C0727E4D5DCD0EB7289384B/* Not supported: data(FF FB 49 38 01) */; internal static readonly __StaticArrayInitTypeSize=231 4E0132ED4E2A32B43302E7EABD2AE75B6D2BED4A4F3DC9A3FFE9357BCB0F3461/* Not supported: data(00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5A 50 4B 45 3F 38 31 28 22 1D 14 12 0A 00 00 00 00 00 00 00 00 6E 64 5A 54 4E 47 41 3A 33 2D 27 20 1A 14 0C 00 00 00 00 00 00 76 6E 67 5D 56 50 4B 46 41 3B 35 2F 28 1F 17 0F 04 00 00 00 00 7E 77 70 68 5F 59 53 4E 48 42 3C 36 2F 27 20 19 11 0C 01 00 00 86 7F 78 72 67 61 5B 55 4E 48 42 3C 36 2F 29 23 1D 17 10 0A 01 90 89 82 7C 71 6B 65 5F 58 52 4C 46 40 39 33 2D 27 21 1A 0F 01 98 91 8A 84 7B 75 6F 69 62 5C 56 50 4A 43 3D 37 31 2B 24 14 01 A2 9B 94 8E 85 7F 79 73 6C 66 60 5A 54 4D 47 41 3B 35 2E 1E 01 AC A5 9E 98 8F 89 83 7D 76 70 6A 64 5E 57 51 4B 45 3F 38 2D 14 C8 C8 C8 C8 C8 C8 C8 C8 C6 C1 BC B7 B2 AD A8 A3 9E 99 94 81 68) */; internal static readonly __StaticArrayInitTypeSize=5 4FFD7BA0A1C2DEDD668BACD898D9C9E7DC73AE27E8FEB0B37C61F9BE07E003CC/* Not supported: data(F7 13 5E 1D F7) */; internal static readonly __StaticArrayInitTypeSize=25 52A2FED71A9FEFF75E920111E6B4FF3062E2B0DEAA1AA27196C339241BE4DD72/* Not supported: data(F9 F7 F6 F5 F4 EA D2 CA C9 C8 C5 AE 52 3B 38 37 36 2E 16 0C 0B 0A 09 07 00) */; internal static readonly __StaticArrayInitTypeSize=1920 5344C43715572E57EF0F0CF092890B7E8468ADD8B5AC02864F7A02308D771CB0/* Not supported: data(FF 7F 00 00 FE 7F 53 FE F5 7F A6 FC E7 7F F9 FA D4 7F 4D F9 BA 7F A1 F7 9B 7F F6 F5 77 7F 4A F4 4C 7F 9F F2 1D 7F F5 F0 E8 7E 4B EF AD 7E A3 ED 6C 7E FB EB 27 7E 54 EA DB 7D AD E8 8A 7D 07 E7 33 7D 63 E5 D8 7C C1 E3 77 7C 1E E2 10 7C 7D E0 A4 7B DF DE 33 7B 41 DD BB 7A A6 DB 3E 7A 0C DA BD 79 72 D8 36 79 DC D6 A9 78 47 D5 17 78 B4 D3 80 77 23 D2 E4 76 93 D0 42 76 04 CF 9B 75 79 CD F0 74 F0 CB 3E 74 6A CA 89 73 E5 C8 CE 72 63 C7 0D 72 E5 C5 48 71 67 C4 7D 70 ED C2 AE 6F 76 C1 DB 6E 00 C0 02 6E 8F BE 24 6D 21 BD 42 6C B4 BB 5A 6B 4B BA 6E 6A E3 B8 7E 69 80 B7 88 68 21 B6 8E 67 C4 B4 91 66 6A B3 8D 65 15 B2 86 64 C2 B0 7A 63 73 AF 6A 62 28 AE 56 61 DF AC 3D 60 9B AB 21 5F 5A AA FF 5D 1E A9 DA 5C E5 A7 B1 5B AF A6 83 5A 7D A5 52 59 50 A4 1D 58 27 A3 E4 56 01 A2 A7 55 E0 A0 66 54 C4 9F 22 53 AB 9E DA 51 96 9D 8E 50 87 9C 40 4F 7B 9B ED 4D 73 9A 97 4C 71 99 3D 4B 73 98 E2 49 78 97 81 48 84 96 1D 47 92 95 B6 45 A7 94 4D 44 BF 93 E2 42 DC 92 73 41 FE 91 01 40 26 91 8C 3E 52 90 14 3D 83 8F 9A 3B B9 8E 1E 3A F3 8D 9E 38 33 8D 1C 37 78 8C 98 35 C3 8B 11 34 12 8B 89 32 65 8A FC 30 BE 89 6E 2F 1D 89 E0 2D 80 88 4E 2C E9 87 BB 2A 57 87 26 29 CA 86 8F 27 44 86 F6 25 C2 85 5B 24 46 85 BF 22 CF 84 22 21 5C 84 83 1F F1 83 E2 1D 8A 83 41 1C 28 83 9F 1A CD 82 F9 18 76 82 55 17 25 82 AD 15 DA 81 07 14 94 81 5F 12 53 81 B6 10 19 81 0C 0F E3 80 62 0D B4 80 B7 0B 8A 80 0C 0A 65 80 60 08 46 80 B4 06 2C 80 07 05 1A 80 5C 03 0B 80 AE 01 02 80 00 00 01 80 53 FE 02 80 A6 FC 0B 80 F9 FA 19 80 4D F9 2C 80 A1 F7 46 80 F6 F5 65 80 4A F4 89 80 9F F2 B4 80 F5 F0 E3 80 4B EF 18 81 A3 ED 53 81 FB EB 94 81 54 EA D9 81 AD E8 25 82 07 E7 76 82 63 E5 CD 82 C1 E3 28 83 1E E2 89 83 7D E0 F0 83 DF DE 5C 84 41 DD CD 84 A6 DB 45 85 0C DA C2 85 72 D8 43 86 DC D6 CA 86 47 D5 57 87 B4 D3 E9 87 23 D2 80 88 93 D0 1C 89 04 CF BE 89 79 CD 65 8A F0 CB 10 8B 6A CA C2 8B E5 C8 77 8C 63 C7 32 8D E5 C5 F3 8D 67 C4 B8 8E ED C2 83 8F 76 C1 52 90 00 C0 25 91 8F BE FE 91 21 BD DC 92 B4 BB BE 93 4B BA A6 94 E3 B8 92 95 80 B7 82 96 21 B6 78 97 C4 B4 72 98 6A B3 6F 99 15 B2 73 9A C2 B0 7A 9B 73 AF 86 9C 28 AE 96 9D DF AC AA 9E 9B AB C3 9F 5A AA DF A0 1E A9 01 A2 E5 A7 26 A3 AF A6 4F A4 7D A5 7D A5 50 A4 AE A6 27 A3 E3 A7 01 A2 1C A9 E0 A0 59 AA C4 9F 9A AB AB 9E DE AC 96 9D 26 AE 87 9C 72 AF 7B 9B C0 B0 73 9A 13 B2 71 99 69 B3 73 98 C3 B4 78 97 1E B6 84 96 7F B7 92 95 E3 B8 A7 94 4A BA BF 93 B3 BB DC 92 1E BD FE 91 8D BE 26 91 FF BF 52 90 74 C1 83 8F EC C2 B9 8E 66 C4 F3 8D E2 C5 33 8D 62 C7 78 8C E4 C8 C3 8B 68 CA 12 8B EF CB 65 8A 77 CD BE 89 04 CF 1D 89 92 D0 80 88 20 D2 E9 87 B2 D3 57 87 45 D5 CA 86 DA D6 44 86 71 D8 C2 85 0A DA 46 85 A5 DB CF 84 41 DD 5C 84 DE DE F1 83 7D E0 8A 83 1E E2 28 83 BF E3 CD 82 61 E5 76 82 07 E7 25 82 AB E8 DA 81 53 EA 94 81 F9 EB 53 81 A1 ED 19 81 4A EF E3 80 F4 F0 B4 80 9E F2 8A 80 49 F4 65 80 F4 F5 46 80 A0 F7 2C 80 4C F9 1A 80 F9 FA 0B 80 A4 FC 02 80 52 FE 01 80 00 00 02 80 AD 01 0B 80 5A 03 19 80 07 05 2C 80 B3 06 46 80 5F 08 65 80 0A 0A 89 80 B6 0B B4 80 61 0D E3 80 0B 0F 18 81 B5 10 53 81 5D 12 94 81 05 14 D9 81 AC 15 25 82 53 17 76 82 F9 18 CD 82 9D 1A 28 83 3F 1C 89 83 E2 1D F0 83 83 1F 5C 84 21 21 CD 84 BF 22 45 85 5A 24 C2 85 F4 25 43 86 8E 27 CA 86 24 29 57 87 B9 2A E9 87 4C 2C 80 88 DD 2D 1C 89 6D 2F BE 89 FC 30 65 8A 87 32 10 8B 10 34 C2 8B 96 35 77 8C 1B 37 32 8D 9D 38 F3 8D 1B 3A B8 8E 99 3B 83 8F 13 3D 52 90 8A 3E 25 91 00 40 FE 91 71 41 DC 92 DF 42 BE 93 4C 44 A6 94 B5 45 92 95 1D 47 82 96 80 48 78 97 DF 49 72 98 3C 4B 6F 99 96 4C 73 9A EB 4D 7A 9B 3E 4F 86 9C 8D 50 96 9D D8 51 AA 9E 21 53 C3 9F 65 54 DF A0 A6 55 01 A2 E2 56 26 A3 1B 58 4F A4 51 59 7D A5 83 5A AE A6 B0 5B E3 A7 D9 5C 1C A9 FF 5D 59 AA 20 5F 9A AB 3C 60 DE AC 55 61 26 AE 6A 62 72 AF 79 63 C0 B0 85 64 13 B2 8D 65 69 B3 8F 66 C3 B4 8D 67 1E B6 88 68 7F B7 7C 69 E3 B8 6E 6A 4A BA 59 6B B3 BB 41 6C 1E BD 24 6D 8D BE 02 6E FF BF DA 6E 74 C1 AE 6F EC C2 7D 70 66 C4 47 71 E2 C5 0D 72 62 C7 CD 72 E4 C8 88 73 68 CA 3D 74 EF CB EE 74 77 CD 9B 75 04 CF 42 76 92 D0 E3 76 20 D2 80 77 B2 D3 17 78 45 D5 A9 78 DA D6 36 79 71 D8 BC 79 0A DA 3E 7A A5 DB BA 7A 41 DD 31 7B DE DE A4 7B 7D E0 0F 7C 1E E2 76 7C BF E3 D8 7C 61 E5 33 7D 07 E7 8A 7D AB E8 DB 7D 53 EA 26 7E F9 EB 6C 7E A1 ED AD 7E 4A EF E7 7E F4 F0 1D 7F 9E F2 4C 7F 49 F4 76 7F F4 F5 9B 7F A0 F7 BA 7F 4C F9 D4 7F F9 FA E6 7F A4 FC F5 7F 52 FE FE 7F 00 00 FF 7F AD 01 FE 7F 5A 03 F5 7F 07 05 E7 7F B3 06 D4 7F 5F 08 BA 7F 0A 0A 9B 7F B6 0B 77 7F 61 0D 4C 7F 0B 0F 1D 7F B5 10 E8 7E 5D 12 AD 7E 05 14 6C 7E AC 15 27 7E 53 17 DB 7D F9 18 8A 7D 9D 1A 33 7D 3F 1C D8 7C E2 1D 77 7C 83 1F 10 7C 21 21 A4 7B BF 22 33 7B 5A 24 BB 7A F4 25 3E 7A 8E 27 BD 79 24 29 36 79 B9 2A A9 78 4C 2C 17 78 DD 2D 80 77 6D 2F E4 76 FC 30 42 76 87 32 9B 75 10 34 F0 74 96 35 3E 74 1B 37 89 73 9D 38 CE 72 1B 3A 0D 72 99 3B 48 71 13 3D 7D 70 8A 3E AE 6F 00 40 DB 6E 71 41 02 6E DF 42 24 6D 4C 44 42 6C B5 45 5A 6B 1D 47 6E 6A 80 48 7E 69 DF 49 88 68 3C 4B 8E 67 96 4C 91 66 EB 4D 8D 65 3E 4F 86 64 8D 50 7A 63 D8 51 6A 62 21 53 56 61 65 54 3D 60 A6 55 21 5F E2 56 FF 5D 1B 58 DA 5C 51 59 B1 5B 83 5A 83 5A B0 5B 52 59 D9 5C 1D 58 FF 5D E4 56 20 5F A7 55 3C 60 66 54 55 61 22 53 6A 62 DA 51 79 63 8E 50 85 64 40 4F 8D 65 ED 4D 8F 66 97 4C 8D 67 3D 4B 88 68 E2 49 7C 69 81 48 6E 6A 1D 47 59 6B B6 45 41 6C 4D 44 24 6D E2 42 02 6E 73 41 DA 6E 01 40 AE 6F 8C 3E 7D 70 14 3D 47 71 9A 3B 0D 72 1E 3A CD 72 9E 38 88 73 1C 37 3D 74 98 35 EE 74 11 34 9B 75 89 32 42 76 FC 30 E3 76 6E 2F 80 77 E0 2D 17 78 4E 2C A9 78 BB 2A 36 79 26 29 BC 79 8F 27 3E 7A F6 25 BA 7A 5B 24 31 7B BF 22 A4 7B 22 21 0F 7C 83 1F 76 7C E2 1D D8 7C 41 1C 33 7D 9F 1A 8A 7D F9 18 DB 7D 55 17 26 7E AD 15 6C 7E 07 14 AD 7E 5F 12 E7 7E B6 10 1D 7F 0C 0F 4C 7F 62 0D 76 7F B7 0B 9B 7F 0C 0A BA 7F 60 08 D4 7F B4 06 E6 7F 07 05 F5 7F 5C 03 FE 7F AE 01) */; internal static readonly __StaticArrayInitTypeSize=3 535E1BF5C17FD0EDA6D1BA97BF848899FB3AC62748147F53806A6C115D583A00/* Not supported: data(08 10 20) */; internal static readonly __StaticArrayInitTypeSize=16 54671CA12061A6851837605366BBAFDAAD2596F10312651B5A6BD6E2B7C607EA/* Not supported: data(00 40 CA 45 1B 4C FF 52 82 5A B3 62 A2 6B 60 75) */; internal static readonly __StaticArrayInitTypeSize=12 5702BF41FE5248E9043DC00A2D5F3491B198F4E87E815575FB02778A4840D6EE/* Not supported: data(19 00 00 00 0F 00 00 00 02 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=84 5936BC1A9C26369B11F668B7589E741777E5B690EDC9922BE0D6E8E3D59FFD0C/* Not supported: data(01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 03 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 08 00 00 00 08 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 5D90E69C7F51C316E7B52F419B6A22D37E60C423FE3F09FD618C45F93B51D1E6/* Not supported: data(F6 0F 4D 3C F1) */; internal static readonly __StaticArrayInitTypeSize=5 5E902D96A06CBAEAD492828C181E5F7D875A66C2DD28615A9CEB4F91C3F150EF/* Not supported: data(51 05 0B 03 07) */; internal static readonly __StaticArrayInitTypeSize=5 611821F9A6EA0798E5A85301FE3B18CFBAE63CEEE10D69441D66BE9565D19B1A/* Not supported: data(FF 23 4F F3 13) */; internal static readonly __StaticArrayInitTypeSize=44 6172CDEB92FE8A55295F07E552B5007DAC6535E493323DC9E1AA0E6B311AF348/* Not supported: data(00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 0A 00 0C 00 0E 00 10 00 14 00 18 00 1C 00 22 00 28 00 30 00 3C 00 4E 00 64 00) */; internal static readonly __StaticArrayInitTypeSize=5 64974D650E29C4DF5F8E80ED7CC71931B1941ECF108CC235B6ECF4E56010AD7E/* Not supported: data(00 FA 78 37 DC) */; internal static readonly __StaticArrayInitTypeSize=5 64C0B0B130C0199126301650F3F1B2DC32ED4645495802C1BC8E4FA7E17DB450/* Not supported: data(F5 2A 58 04 01) */; internal static readonly __StaticArrayInitTypeSize=72 66C50D3820E57A0FB2AA23835660608CF9DEC570801506DEEBA22D69C6E15DF1/* Not supported: data(FF FE FD EE 0E 03 02 01 00 FF FE FC DA 23 03 02 01 00 FF FE FA D0 3B 04 02 01 00 FF FE F6 C2 47 0A 02 01 00 FF FC EC B7 52 08 02 01 00 FF FC EB B4 5A 11 02 01 00 FF F8 E0 AB 61 1E 04 01 00 FF FE EC AD 5F 25 07 01 00) */; internal static readonly __StaticArrayInitTypeSize=72 6759639A2022703B214E8B5CE3C168BE74CDF5FA1881D6987ED3AE28B02951BA/* Not supported: data(FF FF FF 83 06 91 FF FF FF FF FF EC 5D 0F 60 FF FF FF FF FF C2 53 19 47 DD FF FF FF FF A2 49 22 42 A2 FF FF FF D2 7E 49 2B 39 AD FF FF FF C9 7D 47 30 3A 82 FF FF FF A6 6E 49 39 3E 68 D2 FF FF FB 7B 41 37 44 64 AB FF) */; internal static readonly __StaticArrayInitTypeSize=72 67AAC816BD3D23A7FFB5D5179E5C96C6A94B991CBB517AEBE1011708D5723AFB/* Not supported: data(FF FF FF 9C 04 9A FF FF FF FF FF E3 66 0F 5C FF FF FF FF FF D5 53 18 48 EC FF FF FF FF 96 4C 21 3F D6 FF FF FF BE 79 4D 2B 37 B9 FF FF FF F5 89 47 2B 3B 8B FF FF FF FF 83 42 32 42 6B C2 FF FF A6 74 4C 37 35 7D FF FF) */; internal static readonly __StaticArrayInitTypeSize=5 67FB73BA9EA65E8D8B7F06A481FDC88640266423FBC8B61B4CBA3089B2571E24/* Not supported: data(F1 21 44 02 17) */; internal static readonly long 69157B437BFA517881F950B4360B1A3CF357C129AAA83787664316A3D80035C9/* Not supported: data(00 FF 00 FF 00 FF 00 FF) */; internal static readonly __StaticArrayInitTypeSize=32 69A0F65F36164C3343D76E04AD8935FCF107ADC95A671212089AA44387372A8A/* Not supported: data(95 8B 00 00 37 98 00 00 FF A5 00 00 04 B5 00 00 67 C5 00 00 45 D7 00 00 C1 EA 00 00 FF FF 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 69D72C56982D31D1220C72345A2F4D8D200C3F999A3D843113EA93CB921828DC/* Not supported: data(03 FF 15 10 29) */; internal static readonly __StaticArrayInitTypeSize=18 6C5AD559675FB13E9E1BA54AACEA3B55798AAFF0098BA72616A42442B636AABE/* Not supported: data(B3 8A 8C 94 97 95 99 97 A3 74 43 52 3B 5C 48 64 59 5C) */; internal static readonly __StaticArrayInitTypeSize=42 6D31B9449D93B405878FA12DD59F3D58325D6C024C6201E657DD9024D5C961DC/* Not supported: data(FE 31 43 4D 52 5D 63 C6 0B 12 18 1F 24 2D FF 2E 42 4E 57 5E 68 D0 0E 15 20 2A 33 42 FF 5E 68 6D 70 73 76 F8 35 45 50 58 5F 66) */; internal static readonly __StaticArrayInitTypeSize=12 6DAFAF1D671F78F3E39B14834E7960B1D6E38639E1E9BACC98CA651052EDF659/* Not supported: data(0A 67 F2 0E 56 CD E4 1D 0A 67 F2 0E) */; internal static readonly __StaticArrayInitTypeSize=7 6EA9280C1A6004EB6C262E6BE1255EFF410EFC73BA95B1011062C4F81FC8F4D3/* Not supported: data(00 04 01 02 03 05 06) */; internal static readonly __StaticArrayInitTypeSize=18 6EF9A360CEFD3DEC007EC25CAD0AF3BEAF39345B70D6B1E27CA330A7112B7840/* Not supported: data(45 2F 43 6F A6 CD FF FF FF FF FF FF FF FF FF FF FF FF) */; internal static readonly __StaticArrayInitTypeSize=32 6F86C30FE8E71D998F8C24260B1782C9572A9CBD69E8367C62A4045AB8D99553/* Not supported: data(05 00 18 00 03 00 08 00 02 00 04 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=18 71F30185C034E15F02DE36928A4A64CE4B0CB7F417E3AD5040F30D807FD82791/* Not supported: data(EF BB 74 3B 1C 10 0B 0A 09 08 07 06 05 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=6 730FF0CBCF5C5CE6361F8B2B554310CAAAC463C3CF875C1A5B073CCF43407DB1/* Not supported: data(D2 06 8A 3A AB 98) */; internal static readonly __StaticArrayInitTypeSize=9 7319E7DAA805D47FB2B04C667FEEE44CB723BFE57B1EEDF51912537381FCEF78/* Not supported: data(F1 BE B2 84 57 4A 29 0E 00) */; internal static readonly int 76349DE5D01302DF92511C1D27F32EDB3908EB3CE18A5269013E4E29F95F6502/* Not supported: data(19 17 02 00) */; internal static readonly __StaticArrayInitTypeSize=5 7772525849F424453D0AF17F44F0244AE32BC2972BBF5D1D1CAF064FC2326F3A/* Not supported: data(FE 3C 41 06 FC) */; internal static readonly __StaticArrayInitTypeSize=41 789ADC8AE11180A028C643ACB0C1574C2940BA3007FFD390634A5559BC45E2BC/* Not supported: data(FA F5 EA CB 47 32 2A 26 23 21 1F 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00) */; internal static readonly long 79298A76F3C1106C6EB29321C5E06C70C6D44D136F24DB2E8E062D019C39DA18/* Not supported: data(00 FE 00 FD 03 00 01 FF) */; internal static readonly __StaticArrayInitTypeSize=5 79620CF37BABBFA32655FD0F2545433D000635BDCDD3D9396613BA3975233FFE/* Not supported: data(14 00 4B 03 EF) */; internal static readonly __StaticArrayInitTypeSize=12 79E94B9A7D0FE8EB65FC8FA3C54BD46739D25C08D48A11EF87DC8899A64C80F8/* Not supported: data(13 F5 95 E6 59 12 F3 29 1F 06 54 20) */; internal static readonly __StaticArrayInitTypeSize=18 7C459FACAE3D7EFBB2A8F8914C540821F51581A77B922DB3D8EBFFE2672166B0/* Not supported: data(7D 4A 3B 45 61 8D B6 FF FF FF FF FF FF FF FF FF FF FF) */; internal static readonly int 805E5EF472ED0F9C8DA9FD2E28B6FAFCAE7A3EC60E04D51029A720F7B57CE379/* Not supported: data(C0 80 40 00) */; internal static readonly __StaticArrayInitTypeSize=88 805F24D028E0414D2583430D05F5E007F0EF784950CE4C75A5D2F1394A9DD83E/* Not supported: data(00 00 00 00 02 00 00 00 04 00 00 00 06 00 00 00 08 00 00 00 0A 00 00 00 0C 00 00 00 0E 00 00 00 10 00 00 00 14 00 00 00 18 00 00 00 1C 00 00 00 20 00 00 00 28 00 00 00 30 00 00 00 38 00 00 00 44 00 00 00 50 00 00 00 60 00 00 00 78 00 00 00 9C 00 00 00 C8 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=32 826360E00B18ABA6C894E496DCD24B417310D4248A85E7036D0FE03CD96AA867/* Not supported: data(05 00 30 00 03 00 10 00 04 00 04 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=18 83244C596AC329521CF92840F2DFF90C93449064626F33174D475A7FC3A47D72/* Not supported: data(D5 A2 74 53 3B 2B 20 18 12 0F 0C 09 07 06 05 03 02 00) */; internal static readonly __StaticArrayInitTypeSize=5 84954C75F7E4E97CD79C269516AD654EB71607063EBFA29C367B32A34C253591/* Not supported: data(02 00 4D 0B 09) */; internal static readonly long 893B0446E8B5DBF22874C9AE43F6ABD46131C726A20E9FB9231CCE2338D5124E/* Not supported: data(00 FF 00 FE 01 00 01 FF) */; internal static readonly __StaticArrayInitTypeSize=12 8A440785CCF05990CE3ACF9AE347F986055ABCE36958CB1F140A45A3470C2083/* Not supported: data(A5 77 50 3D 2F 23 1B 14 0E 09 04 00) */; internal static readonly __StaticArrayInitTypeSize=7 8A86036737211FA88BFF83EA33D262A5FD9CE273A6B530399EF13AC9EACC5C6F/* Not supported: data(D7 C3 A6 7D 6E 52 00) */; internal static readonly __StaticArrayInitTypeSize=88 8B39078EDAC0092AF05D4D7487ADA17E58EC54A596FCBE2EA73CE0F58FFF0150/* Not supported: data(01 00 00 00 02 00 00 00 04 00 00 00 06 00 00 00 08 00 00 00 0A 00 00 00 0C 00 00 00 0E 00 00 00 10 00 00 00 14 00 00 00 18 00 00 00 1C 00 00 00 20 00 00 00 28 00 00 00 30 00 00 00 38 00 00 00 44 00 00 00 50 00 00 00 60 00 00 00 78 00 00 00 A0 00 00 00 C8 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=152 8C2E521C19CCB88B51E420D0152C34725D7B65F5DCC9A388EE192D5759A6E34B/* Not supported: data(81 00 CB 36 00 EA 81 17 00 F5 B8 49 0A 00 FA D7 81 29 05 00 FC E8 AD 56 18 03 00 FD F0 C8 81 38 0F 02 00 FD F4 D9 A4 5E 26 0A 01 00 FD F5 E2 BD 84 47 1B 07 01 00 FD F6 E7 CB 9F 69 38 17 06 01 00 FF F8 EB D5 B3 85 55 2F 13 05 01 00 FF FE F3 DD C2 9F 75 46 25 0C 02 01 00 FF FE F8 EA D0 AB 80 55 30 16 08 02 01 00 FF FE FA F0 DC BD 95 6B 43 24 10 06 02 01 00 FF FE FB F3 E3 C9 A6 80 5A 37 1D 0D 05 02 01 00 FF FE FC F6 EA D5 B7 93 6D 49 2B 16 0A 04 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=16 8D1B611311DAA070458FBB0561F81B36562622DEF99A0F1E631991234CA70C87/* Not supported: data(00 73 00 00 00 66 00 00 00 53 00 00 00 40 00 00) */; internal static readonly __StaticArrayInitTypeSize=54 8D74C68FBCA3971B9C8BCD12C4396BD9000F437169CB19EBA3170DDC14A0E77D/* Not supported: data(4F 2F 4C 26 2B 20 BC 1B 5F 18 BD 15 9E 13 DF 11 6A 10 2D 0F 1C 0E 2F 0D 5F 0C A8 0B 04 0B 72 0A EE 09 76 09 09 09 A6 08 4B 08 F6 07 A9 07 61 07 1E 07 E0 06 A6 06) */; internal static readonly __StaticArrayInitTypeSize=1688 8EB034A22CAA84347E53F2E0F50BC3D01133044CB2EAFA48054D10BC9B01402B/* Not supported: data(0E BE C0 BD AC 1F 9B BE 95 82 1A BF 96 95 46 BE 54 72 3E BE 92 03 1A BF 06 98 3E BD 02 A0 EA BD B6 2B D4 BD B9 72 1E BF 6A BE A2 BE 1C 07 2E BE 6B F3 8F BD 5A 9E 17 3E 21 AD D1 3E 0A 66 0C 3F 7D 3C BC 3E 14 21 FD BE 8F A9 43 3F 08 77 EB BF 0A F3 2E 3E 75 93 4C 41 50 53 8B BF 6C EC A2 BF B5 15 82 C1 1C 6B C1 41 A2 62 B2 C0 FF E7 30 BE 2F 4F 27 BE 9E CE 65 BE FF 57 C2 BD 9B 3C 95 BD CB F8 87 BE 2C 61 CD BD CB 21 53 BD 40 A6 15 BE EE 23 F7 BD A0 FD 38 BE DB A7 03 3E E9 5F E2 3E D5 CA FC BE 1D CB 2B 3E E7 A8 53 3E 01 4F 4A BE F7 03 D6 3E 47 77 C0 3F AD F9 45 BF 40 A4 20 C1 2B C2 CD 3E C0 B2 3E 40 C9 76 73 41 64 CC F1 BF 27 A5 98 BF 17 CC E9 3C 86 C1 84 BB C9 E8 90 3D 54 48 07 3C 9A E7 BD BD 67 47 2A BC 3B 89 8C BB 9F 7A A0 BB 58 5A 91 BD 55 C4 27 BB A9 0B 22 3D B1 DB 67 3E F1 36 05 3D 34 11 26 3E AA 0A CD BD 56 B9 F8 3E 6C 04 02 3E 56 66 92 3E E4 FE 7E 3C 6A FB D7 3D 9F 8E 43 40 88 46 93 3F 39 28 81 BF 47 5A EA BF 8B 54 54 40 D2 35 5B C0 0D FD F3 BD E8 27 26 BD 19 1F E2 3B F1 5A 93 3C AB AA 1C BD ED EE C3 3B 05 6A 96 BC F6 8D F9 3A 25 C9 13 BE 6A 73 32 BD D2 D6 81 3A A1 64 62 3E 9E D2 11 3E 80 D7 F7 3E DD 0C CF 3E 7C 0F 03 3F FA F2 72 BE 37 8B 77 3E 2F 6E B3 3E B7 0D 33 BF 88 63 26 41 12 A5 29 40 53 D0 1B C0 35 07 86 C0 7D 96 87 3F 3C F7 DA 3F 0C D4 DA 3B BA BA 93 BD BF C0 22 BD 45 90 14 3D 26 70 EB BD D0 25 C1 BC D2 9C 06 3C 7C 3A 68 BC 72 0B 07 BD 1F 1A 11 BD AB CC 35 3B 9A D0 94 BE DA E6 92 BF 8C 68 A3 BE 59 C1 2F BF A3 E9 BC 3E 40 32 F5 3E FD F5 3A 3E A3 77 D2 BE 08 90 61 3F 27 6B 93 C0 21 1F BC 3F E0 F3 AB 3E A1 D6 E8 BF F5 5B F1 C1 08 AC B1 40 FC B1 FF 3A 6A 15 FD BD 25 F5 94 BD 29 66 83 BD FC E9 5A BD 23 86 DD BD 14 F9 BF BD 2B ED 8E BD 4B AB E1 BC A7 EC 44 BE 7A 6E E1 BD AC 1C 92 3E 69 AA CF BE 07 CB BD 3D 23 65 93 BE C9 E7 59 BF FC C2 CB BD D4 5F 6F BE 6F 81 A4 BF 0D 6C 91 3F 9B C9 47 40 BB 27 8F BD 42 5B EE BF 71 C9 29 40 78 EE E9 C0 1A A8 1C 40 87 8A 92 BA 36 98 81 BD 7F 21 1A BD 8A 72 19 BE E5 64 12 3E F7 CA 3C 3E 71 CA FC 3D 75 DC 9A 3D 46 41 F0 3D C8 28 BF 3D 47 C1 8D 3D 16 90 AC 3D AF 51 90 3D 1B A6 71 3D AD F6 C0 3D 3D D1 E5 BE 5C 2F D7 3C 94 6B 8A 3E 6A 4E 86 BE 62 BA 30 3E 31 25 00 40 85 09 23 BE 63 60 1D 3D 1A 51 23 41 B6 F8 84 40 07 CE 15 C0 78 63 61 BD 4F 12 1E 3C 62 BA 10 BE 08 DF E0 3C BB DE 0C 3D 88 A6 47 BD 61 98 C2 3D 23 F5 FD BB 9E 92 18 BD B9 9B B3 BB BB EC 87 BD 2D B6 C4 3D E6 CE 4C BE 0C 18 29 BD FB 57 16 3F 30 44 53 3D 8E AC AC 3E DA E2 5A 3F 5D 1A 2B 3F CA 52 EB BD B2 4B 68 C0 25 59 EF BE B1 A4 5C BE 39 62 27 40 91 EE CF 3E B4 8E AE BF CB 3D 2E 3D 14 05 FA 3D D2 62 BF 3D 43 04 FC 3D A0 A5 0B 3D 9B E2 11 BE F5 82 0F 3D 0F FA 48 BD 37 29 96 3D 71 34 6C 3D 53 EB FD 3D B9 D7 53 BD 93 8B 81 BE 45 2F 17 3F 71 59 15 3E EE 5F A1 3E CF D9 62 3E B1 A8 18 BE 4F 59 5D 3E 7F FB B2 BE FD 87 C4 41 A1 83 7E BF 0B 42 1D 3F F2 52 96 C1 1B 4C 35 C0 45 80 37 BF 54 C4 B1 BE FD 82 F5 3E 80 EE 7B BE D7 60 9B 3D 89 96 0C 3E D3 13 36 BE B9 33 F3 3D 2E FD 8D BA AF 07 73 BE 81 22 B6 3E 21 07 05 BE DA 4E 60 BD 65 1C A3 BE 15 AB A6 BE 6B D3 38 3E AB 1F 80 BD B7 9B 10 3E 28 29 B0 3E 18 CF C0 3E 5F 7E 17 BF 66 F7 BA 40 AA F1 C2 BE 2E 38 63 3E EF AC B5 BF 30 6C E5 C9 7A AA AB 3F DA 1F E8 3C 1B 71 37 BD A2 3B AD BC 7F 79 D2 BC 09 C0 64 3C EC 56 AA 3C 65 66 30 BC C6 CF 35 3C CA 0D 70 3D 3E B4 CF BC B2 86 06 BD 79 23 F3 3D 4E 26 5E BE F7 3E 15 3E E6 5D F5 3D 6A 6F BB BD C6 15 F7 BD 29 53 A1 BD 6A 17 13 BE 86 59 18 BF BC 74 93 BF C6 6D A0 BF B5 E0 95 BF 2A E3 8A 40 40 1A 6E C9 F9 66 AF BF CC 4C 24 BD 0D A8 57 3E 8D EF 0B BE 9F 39 0B 3E 40 57 56 BD 1C 1C 36 3D C7 CF 6B 3C EF 38 87 3B AA 1B 9E BC E2 B1 5F 3E A2 B2 E1 BD EC A3 01 C0 A5 11 6B 3F 1C 08 1D C0 86 03 99 3F B8 56 7B BD 30 12 F6 BF BA C0 9D 3E AC CA FE 3E 2A 90 69 3F 66 4B 56 3E 93 18 16 C0 5F 5E 0C 40 27 14 CF C0 90 4E D9 3F A9 A1 39 BF 70 DA 42 3C 4D CE 1A 3D 6D EB 62 3D 6D 82 B9 3C F3 43 90 BD 5D 03 F6 BC B6 7C 49 3C 48 E9 88 BB 3E 9E 8C BD 7D 40 00 3D DB 32 20 3D C2 6C BA 3E F2 A5 C1 BD 7E 50 BC 3C C2 51 32 BE E4 DA A8 3E 2C EF EA 3D 70 B6 99 3E 3E 21 DB 3D 12 88 07 3E 08 94 B9 40 7D 76 68 3F 50 C3 67 BF 58 CA 56 C0 F8 38 43 3E CF A1 3C 3E 32 74 2C BF D0 5E 6D 3E D5 1D 70 BD 41 4A 6C 3E D8 65 E0 BE F0 C1 7B 3E 17 48 30 BE B6 7B B3 3D 79 73 38 BF 55 6A 26 3E 55 BB 8B 3C 8F 72 D0 3D 75 E6 C6 3E D5 26 AA 3F 02 F1 8A 3F 6C B1 6F BF 33 A7 17 C0 42 09 D7 C0 90 66 5C C0 F1 D7 08 40 74 B5 63 41 52 44 9D 40 14 CB 45 C0 10 12 1B C1 FC AA 44 BF A4 E4 E5 3F 4B 23 61 3D 11 52 27 3E 10 3B A3 3D FD DF 0C 3D D3 AF 63 BD ED B2 A5 BB D9 66 99 3C 6E C9 05 3D 22 A2 BD 3C AF 77 1F 3E 9A 0F 43 3D 4B 78 82 BE 97 FF CC 3F D2 1C 4D BF 77 84 23 40 41 D5 3C 3F 13 66 AE BF DD 09 32 BF 47 5A 1C C0 3E AE DD BF 83 FA 7C 40 CD 01 F2 3F 65 E0 F8 3E 4B 59 35 C1 80 93 70 4A F9 4B C3 BE 7E 1D F8 3D 5E 2C 68 BF F9 14 3C 40 33 C4 D1 3F E7 FF 61 3F 02 D5 5F 3F 2D CF 9B 3F 2E E2 5F BF A6 B6 A4 3E 5D F9 48 3F A0 51 72 3F 86 37 13 BF 3E CB 5D C0 22 89 62 3F AD 3E BD 3D 90 83 1E C1 74 5D C8 3E 0A F2 23 3E AA 2B 03 C0 F0 A7 84 40 D2 16 8C 3D 3A 3C 14 BE 7B 10 92 BE 45 2C C2 3E 74 46 94 BF A7 1D E3 BC 9A 99 1D C1 10 5D 9A C0 33 A7 6D 40 8B E0 77 40 1A A3 61 40) */; internal static readonly __StaticArrayInitTypeSize=5 8EC54AD534D71A6AD750C85FD659FD0FB0C5992233E7611C1BCECBAFFC08E190/* Not supported: data(FD 03 5D 1B FC) */; internal static readonly __StaticArrayInitTypeSize=5 8F0894040512F3D81BD5679550D998891D09E42A26ABA42F6E695FDA8F38B56D/* Not supported: data(00 0C 63 06 04) */; internal static readonly __StaticArrayInitTypeSize=7 90E907FF5F9DF7D3B4BDC2D43E7CCA61E7149FC8070FF3335D2A44E6D2AFBFD2/* Not supported: data(64 28 10 07 03 01 00) */; internal static readonly __StaticArrayInitTypeSize=544 91C1A3E8DBFDEEC87E1FB7EC149D64C5712B5056AB5DD572B8D2F22888E6240F/* Not supported: data(C8 51 0C D2 84 F4 EF 3F 00 00 00 00 00 00 F0 3F C8 51 0C D2 84 F4 EF 3F F6 95 07 E9 29 D2 EF 3F DA D3 C4 F1 32 99 EF 3F D4 FD 10 D9 0F 4A EF 3F 7E 9F BB 6E 5B E5 EE 3F 61 C1 3F 9D D9 6B EE 3F 1D D7 F1 25 75 DE ED 3F 6A 7F 6F EC 3C 3E ED 3F C9 EA 35 C1 60 8C EC 3F 77 24 45 01 2E CA EB 3F 1E BC 7E DA 0B F9 EA 3F 3A D0 BF 34 77 1A EA 3F F5 25 23 80 FE 2F E9 3F F2 40 43 83 3D 3B E8 3F 0E 07 53 DE D8 3D E7 3F F7 F2 AF A3 79 39 E6 3F 4C C8 C5 20 C9 2F E5 3F CE B8 78 91 6C 22 E4 3F FF 99 5A 19 01 13 E3 3F 2F 9C 31 ED 17 03 E2 3F 63 D9 06 CD 32 F4 E0 3F 4D 5A 86 72 81 CF DF 3F CD 8F 64 FB 35 BE DD 3F 15 C6 37 90 05 B7 DB 3F E0 07 AD A8 3D BC D9 3F 60 33 0A 93 F3 CF D7 3F F3 1D FC C4 01 F4 D5 3F 4A 85 67 F8 05 2A D4 3F E7 CD 3C 14 60 73 D2 3F 8D CA 34 37 32 D1 D0 3F D8 D1 7A F0 C1 88 CE 3F AF 27 78 12 2A 9B CB 3F C8 48 93 DE 79 DA C8 3F B5 CF 5B 23 1F 47 C6 3F 3D 57 42 14 1F E1 C3 3F B5 CD 01 40 1D A8 C1 3F 4D BA 90 BB C6 36 BF 3F 2E 0C 26 38 D4 73 BB 3F 66 92 05 0A C4 04 B8 3F 80 54 16 C7 79 E6 B4 3F 62 48 4E 26 6E 15 B2 3F A4 15 84 97 85 1B AF 3F EC B2 EB 20 A7 96 AA 3F 97 A8 41 45 93 93 A6 3F 3E 78 2F EF 58 09 A3 3F D5 E7 AC 47 C8 DD 9F 3F 6C CF 4D 17 39 76 9A 3F F4 F1 D8 E8 FF C9 95 3F 0F 0B B5 A6 79 C7 91 3F 55 17 6C FA 1E BB 8C 3F FE A4 B1 28 B2 F7 86 3F 3C B7 96 EA 7E 25 82 3F A5 FB B5 CC 54 4E 7C 3F 67 1F 54 77 9F C2 75 3F 05 C4 7F 15 3B 75 70 3F 74 7F B3 9C 9D 6F 68 3F D3 F0 F3 00 92 C0 61 3F F7 52 DB FA A7 23 59 3F 3F C1 AC ED 79 40 51 3F F1 42 00 91 FA C2 46 3F 7B B2 CD 53 3E 80 3C 3F 26 51 92 22 F0 8F 30 3F C7 54 6E 60 7A 14 21 3F 7D 89 7F 37 20 AB 0B 3F F1 68 E3 88 B5 F8 E4 3E 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=32 925C19506E3D070F12313EED713ADF34E4DCFA87239C35171CCEE8E45C52EEFE/* Not supported: data(FD FA F4 E9 D4 B6 96 83 78 6E 62 55 48 3C 31 28 20 19 13 0F 0D 0B 09 08 07 06 05 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=9 9499549175ED9B9EAF9C3C2055B6F5499213FE29876AB6D0CBF5C90CB0B374DF/* Not supported: data(5F 63 5B 7D 5D 4C 7B 73 7B) */; internal static readonly __StaticArrayInitTypeSize=12 94A44DFE613FDC7B8519BB35A934CFFA1F8027A90F64379F2EE5E880D7ED85CA/* Not supported: data(22 B6 52 05 DA FA A4 0A 22 B6 52 05) */; internal static readonly __StaticArrayInitTypeSize=480 953C107E9B7161DE37DCFADA43992B71DC7771C12CDD36393BA8EA8B3C945BED/* Not supported: data(00 00 30 00 60 00 90 00 C0 00 10 00 40 00 70 00 A0 00 D0 00 20 00 50 00 80 00 B0 00 E0 00 04 00 34 00 64 00 94 00 C4 00 14 00 44 00 74 00 A4 00 D4 00 24 00 54 00 84 00 B4 00 E4 00 08 00 38 00 68 00 98 00 C8 00 18 00 48 00 78 00 A8 00 D8 00 28 00 58 00 88 00 B8 00 E8 00 0C 00 3C 00 6C 00 9C 00 CC 00 1C 00 4C 00 7C 00 AC 00 DC 00 2C 00 5C 00 8C 00 BC 00 EC 00 01 00 31 00 61 00 91 00 C1 00 11 00 41 00 71 00 A1 00 D1 00 21 00 51 00 81 00 B1 00 E1 00 05 00 35 00 65 00 95 00 C5 00 15 00 45 00 75 00 A5 00 D5 00 25 00 55 00 85 00 B5 00 E5 00 09 00 39 00 69 00 99 00 C9 00 19 00 49 00 79 00 A9 00 D9 00 29 00 59 00 89 00 B9 00 E9 00 0D 00 3D 00 6D 00 9D 00 CD 00 1D 00 4D 00 7D 00 AD 00 DD 00 2D 00 5D 00 8D 00 BD 00 ED 00 02 00 32 00 62 00 92 00 C2 00 12 00 42 00 72 00 A2 00 D2 00 22 00 52 00 82 00 B2 00 E2 00 06 00 36 00 66 00 96 00 C6 00 16 00 46 00 76 00 A6 00 D6 00 26 00 56 00 86 00 B6 00 E6 00 0A 00 3A 00 6A 00 9A 00 CA 00 1A 00 4A 00 7A 00 AA 00 DA 00 2A 00 5A 00 8A 00 BA 00 EA 00 0E 00 3E 00 6E 00 9E 00 CE 00 1E 00 4E 00 7E 00 AE 00 DE 00 2E 00 5E 00 8E 00 BE 00 EE 00 03 00 33 00 63 00 93 00 C3 00 13 00 43 00 73 00 A3 00 D3 00 23 00 53 00 83 00 B3 00 E3 00 07 00 37 00 67 00 97 00 C7 00 17 00 47 00 77 00 A7 00 D7 00 27 00 57 00 87 00 B7 00 E7 00 0B 00 3B 00 6B 00 9B 00 CB 00 1B 00 4B 00 7B 00 AB 00 DB 00 2B 00 5B 00 8B 00 BB 00 EB 00 0F 00 3F 00 6F 00 9F 00 CF 00 1F 00 4F 00 7F 00 AF 00 DF 00 2F 00 5F 00 8F 00 BF 00 EF 00) */; internal static readonly __StaticArrayInitTypeSize=5 9583E4C4BF7987642405D65C7E87F1CA1B510C2B7ECFE1C4459C870A8CD9BB12/* Not supported: data(01 01 08 01 01) */; internal static readonly __StaticArrayInitTypeSize=34 961C360B67FC761DEA1D2EAD6E0805A89F0D6D28B9E6E07743A8D40CCF030CB9/* Not supported: data(00 01 00 00 01 00 01 FF 02 FF 02 FF 02 03 FE 03 FE FE 04 04 FD 05 FD FC 06 FC 06 05 FB 08 FA FB F9 09) */; internal static readonly __StaticArrayInitTypeSize=12 9723E36078828845D5C5D57E2358E9E87A45B5240B4E4FF6424A2B5DF13C9801/* Not supported: data(46 11 31 0A ED 03 62 14 46 11 31 0A) */; internal static readonly __StaticArrayInitTypeSize=12 98E051083393385951EEEA3D3F8398E44014D44D09B0DEBD7CDEF156FC71763D/* Not supported: data(06 00 00 00 04 00 00 00 03 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 98FF5E2BFB78ECFC862ACB8138AC56DF73227EBA5796EAB07F75459D344B836D/* Not supported: data(F8 16 2C FA 07) */; internal static readonly __StaticArrayInitTypeSize=58 99716688BF55BC6EC66CC70529F37A780E0EB5CE52A7F4205C815500E98EAE48/* Not supported: data(2A AF D5 C9 CF FF 40 00 11 00 63 FF 61 01 10 FE A3 00 27 2B BD 56 D9 FF 06 00 5B 00 56 FF BA 00 17 00 80 FC C0 18 D8 4D ED FF DC FF 66 00 A7 FF E8 FF 48 01 49 FC 08 0A 25 3E) */; internal static readonly __StaticArrayInitTypeSize=5 9A2DF499C447A8F795BB3ED13F342582E5247FD47F966DE370507BE23B0054EB/* Not supported: data(F7 0F 2A 19 0E) */; internal static readonly __StaticArrayInitTypeSize=40 9BE500C926A32348378C36AA8867C2460DE387E9B7B04297ADF42658FD8B1936/* Not supported: data(87 C7 3D C9 40 00 80 00 86 FF 24 00 36 01 00 FD 48 02 33 24 45 45 0C 00 80 00 12 00 72 FF 20 01 8B FF 9F FC 1B 10 7B 38) */; internal static readonly __StaticArrayInitTypeSize=9 9C52E4E45456B021170EF7060D5CADF00C3314C84564884E261171DE2DC6878F/* Not supported: data(83 4A 8D 4F 50 8A 5F 68 86) */; internal static readonly __StaticArrayInitTypeSize=18 9CCDBE227CB102FA82BF74329CAEEF72702512BAE0853DA06A4C4DF2D8D77DBC/* Not supported: data(7D 33 1A 12 0F 0C 0B 0A 09 08 07 06 05 04 03 02 01 00) */; internal static readonly long 9E47B9557883D843A38B94D1FBF8FA55F935F11A30BD59048397C5789A20B90B/* Not supported: data(FF FC E2 9B 3D 0B 02 00) */; internal static readonly __StaticArrayInitTypeSize=42 9FFAA57C19E65CAEF3480A703F881B9AE5212F336F2C6695900282DBBC5C8F64/* Not supported: data(3D 5A 5D 3C 69 2A 6B 29 6E 2D 74 26 71 26 70 26 7C 1A 84 1B 88 13 8C 14 9B 0E 9F 10 9E 12 AA 0D B1 0A BB 08 C0 06 AF 09 9F 0A) */; internal static readonly __StaticArrayInitTypeSize=5 A1D82C09685DE31854CA9ADD68D1AD3665978B1A985520740ADEA500D95F2722/* Not supported: data(0D 16 27 17 0C) */; internal static readonly __StaticArrayInitTypeSize=5 A3AB51E0C667002EC85D27D5698A59E0FC981FC34687935E01E7705F56316E34/* Not supported: data(F3 2C 7A 04 E8) */; internal static readonly __StaticArrayInitTypeSize=168 A430E8546E86F5D93220B38AAE7704B126DB7C428F9FDFFC43D06DB6E4E14856/* Not supported: data(E0 E0 E0 E0 E0 E0 E0 E0 A0 A0 A0 A0 B9 B9 B9 B2 B2 A8 86 3D 25 E0 E0 E0 E0 E0 E0 E0 E0 F0 F0 F0 F0 CF CF CF C6 C6 B7 90 42 28 A0 A0 A0 A0 A0 A0 A0 A0 B9 B9 B9 B9 C1 C1 C1 B7 B7 AC 8A 40 26 F0 F0 F0 F0 F0 F0 F0 F0 CF CF CF CF CC CC CC C1 C1 B4 8F 42 28 B9 B9 B9 B9 B9 B9 B9 B9 C1 C1 C1 C1 C1 C1 C1 B7 B7 AC 8A 41 27 CF CF CF CF CF CF CF CF CC CC CC CC C9 C9 C9 BC BC B0 8D 42 28 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C2 C2 C2 B8 B8 AD 8B 41 27 CC CC CC CC CC CC CC CC C9 C9 C9 C9 C6 C6 C6 BB BB AF 8C 42 28) */; internal static readonly __StaticArrayInitTypeSize=5 A44068246659F9B8518FBDCB668F0E2C49AB3E7831769E5F17E8BB06D62C88AC/* Not supported: data(27 43 10 FC 01) */; internal static readonly __StaticArrayInitTypeSize=40 A5A45C6B1D576BCC8BCD1C3AAEB699A2E949B44302983603BD0FFDCF1701C589/* Not supported: data(94 6B 67 C4 11 00 0C 00 08 00 01 00 F6 FF EA FF E2 FF E0 FF EA FF 03 00 2C 00 64 00 A8 00 F3 00 3D 01 7D 01 AD 01 C7 01) */; internal static readonly __StaticArrayInitTypeSize=5088 A708167506EE9B9DDFF5E6A5B7867AAC3812331CF40433CC92787496F36AB53A/* Not supported: data(01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 03 00 00 00 05 00 00 00 07 00 00 00 09 00 00 00 0B 00 00 00 0D 00 00 00 0F 00 00 00 11 00 00 00 13 00 00 00 15 00 00 00 17 00 00 00 19 00 00 00 1B 00 00 00 1D 00 00 00 1F 00 00 00 21 00 00 00 23 00 00 00 25 00 00 00 27 00 00 00 29 00 00 00 2B 00 00 00 2D 00 00 00 2F 00 00 00 31 00 00 00 33 00 00 00 35 00 00 00 37 00 00 00 39 00 00 00 3B 00 00 00 3D 00 00 00 3F 00 00 00 41 00 00 00 43 00 00 00 45 00 00 00 47 00 00 00 49 00 00 00 4B 00 00 00 4D 00 00 00 4F 00 00 00 51 00 00 00 53 00 00 00 55 00 00 00 57 00 00 00 59 00 00 00 5B 00 00 00 5D 00 00 00 5F 00 00 00 61 00 00 00 63 00 00 00 65 00 00 00 67 00 00 00 69 00 00 00 6B 00 00 00 6D 00 00 00 6F 00 00 00 71 00 00 00 73 00 00 00 75 00 00 00 77 00 00 00 79 00 00 00 7B 00 00 00 7D 00 00 00 7F 00 00 00 81 00 00 00 83 00 00 00 85 00 00 00 87 00 00 00 89 00 00 00 8B 00 00 00 8D 00 00 00 8F 00 00 00 91 00 00 00 93 00 00 00 95 00 00 00 97 00 00 00 99 00 00 00 9B 00 00 00 9D 00 00 00 9F 00 00 00 A1 00 00 00 A3 00 00 00 A5 00 00 00 A7 00 00 00 A9 00 00 00 AB 00 00 00 AD 00 00 00 AF 00 00 00 B1 00 00 00 B3 00 00 00 B5 00 00 00 B7 00 00 00 B9 00 00 00 BB 00 00 00 BD 00 00 00 BF 00 00 00 C1 00 00 00 C3 00 00 00 C5 00 00 00 C7 00 00 00 C9 00 00 00 CB 00 00 00 CD 00 00 00 CF 00 00 00 D1 00 00 00 D3 00 00 00 D5 00 00 00 D7 00 00 00 D9 00 00 00 DB 00 00 00 DD 00 00 00 DF 00 00 00 E1 00 00 00 E3 00 00 00 E5 00 00 00 E7 00 00 00 E9 00 00 00 EB 00 00 00 ED 00 00 00 EF 00 00 00 F1 00 00 00 F3 00 00 00 F5 00 00 00 F7 00 00 00 F9 00 00 00 FB 00 00 00 FD 00 00 00 FF 00 00 00 01 01 00 00 03 01 00 00 05 01 00 00 07 01 00 00 09 01 00 00 0B 01 00 00 0D 01 00 00 0F 01 00 00 11 01 00 00 13 01 00 00 15 01 00 00 17 01 00 00 19 01 00 00 1B 01 00 00 1D 01 00 00 1F 01 00 00 21 01 00 00 23 01 00 00 25 01 00 00 27 01 00 00 29 01 00 00 2B 01 00 00 2D 01 00 00 2F 01 00 00 31 01 00 00 33 01 00 00 35 01 00 00 37 01 00 00 39 01 00 00 3B 01 00 00 3D 01 00 00 3F 01 00 00 41 01 00 00 43 01 00 00 45 01 00 00 47 01 00 00 49 01 00 00 4B 01 00 00 4D 01 00 00 4F 01 00 00 51 01 00 00 53 01 00 00 55 01 00 00 57 01 00 00 59 01 00 00 5B 01 00 00 5D 01 00 00 5F 01 00 00 0D 00 00 00 19 00 00 00 29 00 00 00 3D 00 00 00 55 00 00 00 71 00 00 00 91 00 00 00 B5 00 00 00 DD 00 00 00 09 01 00 00 39 01 00 00 6D 01 00 00 A5 01 00 00 E1 01 00 00 21 02 00 00 65 02 00 00 AD 02 00 00 F9 02 00 00 49 03 00 00 9D 03 00 00 F5 03 00 00 51 04 00 00 B1 04 00 00 15 05 00 00 7D 05 00 00 E9 05 00 00 59 06 00 00 CD 06 00 00 45 07 00 00 C1 07 00 00 41 08 00 00 C5 08 00 00 4D 09 00 00 D9 09 00 00 69 0A 00 00 FD 0A 00 00 95 0B 00 00 31 0C 00 00 D1 0C 00 00 75 0D 00 00 1D 0E 00 00 C9 0E 00 00 79 0F 00 00 2D 10 00 00 E5 10 00 00 A1 11 00 00 61 12 00 00 25 13 00 00 ED 13 00 00 B9 14 00 00 89 15 00 00 5D 16 00 00 35 17 00 00 11 18 00 00 F1 18 00 00 D5 19 00 00 BD 1A 00 00 A9 1B 00 00 99 1C 00 00 8D 1D 00 00 85 1E 00 00 81 1F 00 00 81 20 00 00 85 21 00 00 8D 22 00 00 99 23 00 00 A9 24 00 00 BD 25 00 00 D5 26 00 00 F1 27 00 00 11 29 00 00 35 2A 00 00 5D 2B 00 00 89 2C 00 00 B9 2D 00 00 ED 2E 00 00 25 30 00 00 61 31 00 00 A1 32 00 00 E5 33 00 00 2D 35 00 00 79 36 00 00 C9 37 00 00 1D 39 00 00 75 3A 00 00 D1 3B 00 00 31 3D 00 00 95 3E 00 00 FD 3F 00 00 69 41 00 00 D9 42 00 00 4D 44 00 00 C5 45 00 00 41 47 00 00 C1 48 00 00 45 4A 00 00 CD 4B 00 00 59 4D 00 00 E9 4E 00 00 7D 50 00 00 15 52 00 00 B1 53 00 00 51 55 00 00 F5 56 00 00 9D 58 00 00 49 5A 00 00 F9 5B 00 00 AD 5D 00 00 65 5F 00 00 21 61 00 00 E1 62 00 00 A5 64 00 00 6D 66 00 00 39 68 00 00 09 6A 00 00 DD 6B 00 00 B5 6D 00 00 91 6F 00 00 71 71 00 00 55 73 00 00 3D 75 00 00 29 77 00 00 19 79 00 00 0D 7B 00 00 05 7D 00 00 01 7F 00 00 01 81 00 00 05 83 00 00 0D 85 00 00 19 87 00 00 29 89 00 00 3D 8B 00 00 55 8D 00 00 71 8F 00 00 91 91 00 00 B5 93 00 00 DD 95 00 00 09 98 00 00 39 9A 00 00 6D 9C 00 00 A5 9E 00 00 E1 A0 00 00 21 A3 00 00 65 A5 00 00 AD A7 00 00 F9 A9 00 00 49 AC 00 00 9D AE 00 00 F5 B0 00 00 51 B3 00 00 B1 B5 00 00 15 B8 00 00 7D BA 00 00 E9 BC 00 00 59 BF 00 00 CD C1 00 00 45 C4 00 00 C1 C6 00 00 41 C9 00 00 C5 CB 00 00 4D CE 00 00 D9 D0 00 00 69 D3 00 00 FD D5 00 00 95 D8 00 00 31 DB 00 00 D1 DD 00 00 75 E0 00 00 1D E3 00 00 C9 E5 00 00 79 E8 00 00 2D EB 00 00 E5 ED 00 00 A1 F0 00 00 3F 00 00 00 81 00 00 00 E7 00 00 00 79 01 00 00 3F 02 00 00 41 03 00 00 87 04 00 00 19 06 00 00 FF 07 00 00 41 0A 00 00 E7 0C 00 00 F9 0F 00 00 7F 13 00 00 81 17 00 00 07 1C 00 00 19 21 00 00 BF 26 00 00 01 2D 00 00 E7 33 00 00 79 3B 00 00 BF 43 00 00 C1 4C 00 00 87 56 00 00 19 61 00 00 7F 6C 00 00 C1 78 00 00 E7 85 00 00 F9 93 00 00 FF A2 00 00 01 B3 00 00 07 C4 00 00 19 D6 00 00 3F E9 00 00 81 FD 00 00 E7 12 01 00 79 29 01 00 3F 41 01 00 41 5A 01 00 87 74 01 00 19 90 01 00 FF AC 01 00 41 CB 01 00 E7 EA 01 00 F9 0B 02 00 7F 2E 02 00 81 52 02 00 07 78 02 00 19 9F 02 00 BF C7 02 00 01 F2 02 00 E7 1D 03 00 79 4B 03 00 BF 7A 03 00 C1 AB 03 00 87 DE 03 00 19 13 04 00 7F 49 04 00 C1 81 04 00 E7 BB 04 00 F9 F7 04 00 FF 35 05 00 01 76 05 00 07 B8 05 00 19 FC 05 00 3F 42 06 00 81 8A 06 00 E7 D4 06 00 79 21 07 00 3F 70 07 00 41 C1 07 00 87 14 08 00 19 6A 08 00 FF C1 08 00 41 1C 09 00 E7 78 09 00 F9 D7 09 00 7F 39 0A 00 81 9D 0A 00 07 04 0B 00 19 6D 0B 00 BF D8 0B 00 01 47 0C 00 E7 B7 0C 00 79 2B 0D 00 BF A1 0D 00 C1 1A 0E 00 87 96 0E 00 19 15 0F 00 7F 96 0F 00 C1 1A 10 00 E7 A1 10 00 F9 2B 11 00 FF B8 11 00 01 49 12 00 07 DC 12 00 19 72 13 00 3F 0B 14 00 81 A7 14 00 E7 46 15 00 79 E9 15 00 3F 8F 16 00 41 38 17 00 87 E4 17 00 19 94 18 00 FF 46 19 00 41 FD 19 00 E7 B6 1A 00 F9 73 1B 00 7F 34 1C 00 81 F8 1C 00 07 C0 1D 00 19 8B 1E 00 BF 59 1F 00 01 2C 20 00 E7 01 21 00 79 DB 21 00 BF B8 22 00 C1 99 23 00 87 7E 24 00 19 67 25 00 7F 53 26 00 C1 43 27 00 E7 37 28 00 F9 2F 29 00 FF 2B 2A 00 01 2C 2B 00 07 30 2C 00 19 38 2D 00 3F 44 2E 00 81 54 2F 00 E7 68 30 00 79 81 31 00 3F 9E 32 00 41 BF 33 00 87 E4 34 00 19 0E 36 00 FF 3B 37 00 41 6E 38 00 E7 A4 39 00 F9 DF 3A 00 7F 1F 3C 00 81 63 3D 00 07 AC 3E 00 19 F9 3F 00 BF 4A 41 00 01 A1 42 00 E7 FB 43 00 79 5B 45 00 BF BF 46 00 C1 28 48 00 87 96 49 00 19 09 4B 00 7F 80 4C 00 C1 FC 4D 00 E7 7D 4F 00 F9 03 51 00 FF 8E 52 00 01 1F 54 00 07 B4 55 00 19 4E 57 00 3F ED 58 00 81 91 5A 00 E7 3A 5C 00 79 E9 5D 00 3F 9D 5F 00 41 56 61 00 87 14 63 00 19 D8 64 00 FF A0 66 00 41 6F 68 00 E7 42 6A 00 F9 1B 6C 00 7F FA 6D 00 41 01 00 00 A9 02 00 00 09 05 00 00 C1 08 00 00 41 0E 00 00 09 16 00 00 A9 20 00 00 C1 2E 00 00 01 41 00 00 29 58 00 00 09 75 00 00 81 98 00 00 81 C3 00 00 09 F7 00 00 29 34 01 00 01 7C 01 00 C1 CF 01 00 A9 30 02 00 09 A0 02 00 41 1F 03 00 C1 AF 03 00 09 53 04 00 A9 0A 05 00 41 D8 05 00 81 BD 06 00 29 BC 07 00 09 D6 08 00 01 0D 0A 00 01 63 0B 00 09 DA 0C 00 29 74 0E 00 81 33 10 00 41 1A 12 00 A9 2A 14 00 09 67 16 00 C1 D1 18 00 41 6D 1B 00 09 3C 1E 00 A9 40 21 00 C1 7D 24 00 01 F6 27 00 29 AC 2B 00 09 A3 2F 00 81 DD 33 00 81 5E 38 00 09 29 3D 00 29 40 42 00 01 A7 47 00 C1 60 4D 00 A9 70 53 00 09 DA 59 00 41 A0 60 00 C1 C6 67 00 09 51 6F 00 A9 42 77 00 41 9F 7F 00 81 6A 88 00 29 A8 91 00 09 5C 9B 00 01 8A A5 00 01 36 B0 00 09 64 BB 00 29 18 C7 00 81 56 D3 00 41 23 E0 00 A9 82 ED 00 09 79 FB 00 C1 0A 0A 01 41 3C 19 01 09 12 29 01 A9 90 39 01 C1 BC 4A 01 01 9B 5C 01 29 30 6F 01 09 81 82 01 81 92 96 01 81 69 AB 01 09 0B C1 01 29 7C D7 01 01 C2 EE 01 C1 E1 06 02 A9 E0 1F 02 09 C4 39 02 41 91 54 02 C1 4D 70 02 09 FF 8C 02 A9 AA AA 02 41 56 C9 02 81 07 E9 02 29 C4 09 03 09 92 2B 03 01 77 4E 03 01 79 72 03 09 9E 97 03 29 EC BD 03 81 69 E5 03 41 1C 0E 04 A9 0A 38 04 09 3B 63 04 C1 B3 8F 04 41 7B BD 04 09 98 EC 04 A9 10 1D 05 C1 EB 4E 05 01 30 82 05 29 E4 B6 05 09 0F ED 05 81 B7 24 06 81 E4 5D 06 09 9D 98 06 29 E8 D4 06 01 CD 12 07 C1 52 52 07 A9 80 93 07 09 5E D6 07 41 F2 1A 08 C1 44 61 08 09 5D A9 08 A9 42 F3 08 41 FD 3E 09 81 94 8C 09 29 10 DC 09 09 78 2D 0A 01 D4 80 0A 01 2C D6 0A 09 88 2D 0B 29 F0 86 0B 81 6C E2 0B 41 05 40 0C A9 C2 9F 0C 09 AD 01 0D C1 CC 65 0D 41 2A CC 0D 09 CE 34 0E A9 C0 9F 0E C1 0A 0D 0F 01 B5 7C 0F 29 C8 EE 0F 09 4D 63 10 81 4C DA 10 81 CF 53 11 09 DF CF 11 29 84 4E 12 01 C8 CF 12 C1 B3 53 13 A9 50 DA 13 09 A8 63 14 41 C3 EF 14 C1 AB 7E 15 09 6B 10 16 A9 0A A5 16 41 94 3C 17 81 11 D7 17 29 8C 74 18 09 0E 15 19 01 A1 B8 19 01 4F 5F 1A 09 22 09 1B 29 24 B6 1B 81 5F 66 1C 41 DE 19 1D A9 AA D0 1D 09 CF 8A 1E C1 55 48 1F 41 49 09 20 09 B4 CD 20 A9 A0 95 21 C1 19 61 22 01 2A 30 23 29 DC 02 24 09 3B D9 24 81 51 B3 25 93 06 00 00 45 0E 00 00 0F 1C 00 00 11 33 00 00 5B 57 00 00 0D 8E 00 00 77 DD 00 00 39 4D 01 00 63 E6 01 00 95 B3 02 00 1F C1 03 00 21 1D 05 00 AB D7 06 00 DD 02 09 00 07 B3 0B 00 C9 FE 0E 00 33 FF 12 00 E5 CF 17 00 2F 8F 1D 00 31 5E 24 00 FB 60 2C 00 AD BE 35 00 97 A1 40 00 59 37 4D 00 03 B1 5B 00 35 43 6C 00 3F 26 7F 00 41 96 94 00 4B D3 AC 00 7D 21 C8 00 27 C9 E6 00 E9 16 09 01 D3 5B 2F 01 85 ED 59 01 4F 26 89 01 51 65 BD 01 9B 0E F7 01 4D 8B 36 02 B7 49 7C 02 79 BD C8 02 A3 5F 1C 03 D5 AE 77 03 5F 2F DB 03 61 6B 47 04 EB F2 BC 04 1D 5C 3C 05 47 43 C6 05 09 4B 5B 06 73 1C FC 06 25 67 A9 07 6F E1 63 08 71 48 2C 09 3B 60 03 0A ED F3 E9 0A D7 D5 E0 0B 99 DF E8 0C 43 F2 02 0E 75 F6 2F 0F 7F DC 70 10 81 9C C6 11 8B 36 32 13 BD B2 B4 14 67 21 4F 16 29 9B 02 18 13 41 D0 19 C5 3C B9 1B 8F C0 BE 1D 91 07 E2 1F DB 55 24 22 8D F8 86 24 F7 45 0B 27 B9 9D B2 29 E3 68 7E 2C 15 1A 70 2F 9F 2D 89 32 A1 29 CB 35 2B 9E 37 39 5D 25 D0 3C 87 63 96 40 49 07 8C 44 B3 C9 B2 48 65 6E 0C 4D AF C3 9A 51 B1 A2 5F 56 7B EF 5C 5B 2D 99 94 60 17 9A 08 66 D9 F7 BA 6B 83 C3 AD 71 B5 19 E3 77 BF 22 5D 7E 1D 23 00 00 71 4D 00 00 91 9C 00 00 FD 26 01 00 65 0C 02 00 E9 77 03 00 99 A2 05 00 35 D6 08 00 2D 70 0D 00 E1 E4 13 00 21 C3 1C 00 ED B7 28 00 75 92 38 00 59 48 4D 00 29 FA 67 00 25 F8 89 00 3D C7 B4 00 51 26 EA 00 B1 13 2C 01 DD D2 7C 01 85 F2 DE 01 C9 52 55 02 B9 2B E3 02 15 14 8C 03 4D 08 54 04 C1 71 3F 05 41 2E 53 06 CD 97 94 07 95 8C 09 09 39 77 B8 0A 49 57 A8 0C 05 CA E0 0E 5D 13 6A 11 31 27 4D 14 D1 B2 93 17 BD 26 48 1B A5 C0 75 1F A9 95 28 24 D9 9C 6D 29 F5 B9 52 2F 6D C8 E6 35 A1 A6 39 3D 61 41 5C 45 AD 9F 60 4E B5 EE 59 58 19 8E 5C 63 69 1C 7E 6F E5 83 D5 7C FF BD 00 00 01 A8 01 00 8F 6B 03 00 F1 9E 06 00 3F 23 0C 00 C1 3D 15 00 8F B6 23 00 F1 FC 39 00 FF 51 5B 00 01 FA 8B 00 0F 75 D1 00 71 BF 32 01 3F 9A B8 01 C1 DC 6D 02 0F CF 5F 03 71 8E 9E 04 FF 7B 3D 06 01 B6 53 08 8F 9C FC 0A F1 61 58 0E 3F A7 8C 12 C1 25 C5 17 8F 65 34 1E F1 81 14 26 FF FB A7 2F 01 9C 3A 3B 0F 62 22 49 71 86 C0 59 3F 8A 82 6D C1 58 E3 84 01 0E 04 00 91 21 09 00 11 2C 13 00 41 EE 25 00 41 4F 47 00 91 43 80 00 11 F7 DD 00 01 46 73 01 01 92 5A 02 11 01 B8 03 91 35 BC 05 41 8F A7 08 41 06 CE 0C 11 B2 9B 12 91 0F 9A 1A 01 1A 76 25 01 4C 07 34 91 9E 57 47 11 9D AC 60 41 A6 91 81 23 51 16 00 C5 9E 32 00 17 B9 6B 00 99 F6 D8 00 6B 89 A0 01 0D C4 FE 02 1F 01 50 05 21 D9 1D 09 33 6C 30 0F D5 A2 A4 18 A7 67 08 27 29 FD 7D 3C 7B B5 E7 5B 1D 77 1D 89 AF A0 2D C9 AD 8E 7B 00 89 E6 19 01 39 96 5E 02 3D 16 D8 04 B5 63 77 09 E1 28 C6 11 21 03 34 20 75 48 82 38 7D 57 57 60 BF 5B AF 02 81 D8 27 06 F7 84 5E 0D E9 FE AD 1B 7F 8B EB 36 81 B7 E5 68 17 03 9C C1 C1 0C FF 0E 39 6A 85 22 19 EE 91 4B 81 78 2B 9E 33 E1 09 54) */; internal static readonly __StaticArrayInitTypeSize=16 A865A97A1F12AE2637DDA63494B5209CDC9D124E574ADCDBD9A064850507154C/* Not supported: data(C7 A5 90 7C 6D 60 54 47 3D 33 2A 20 17 0F 08 00) */; internal static readonly __StaticArrayInitTypeSize=5 A871C903BB3CA690A699C481ACF72A295A4D432BFDF8F58518DA277F7C46CEEE/* Not supported: data(CD 9A 66 33 00) */; internal static readonly __StaticArrayInitTypeSize=64 A900D0A9D722E11691A31B5AE9D4048495B346A5D993D92030E4E4C55820F867/* Not supported: data(E1 CC C9 B8 B7 AF 9E 9A 99 87 77 73 71 6E 6D 63 62 5F 4F 44 34 32 30 2D 2B 20 1F 1B 12 0A 03 00 FF FB EB E6 D4 C9 C4 B6 A7 A6 A3 97 8A 7C 6E 68 5A 4E 4C 46 45 39 2D 22 18 15 0B 06 05 04 03 00) */; internal static readonly __StaticArrayInitTypeSize=152 A94F32BCB7A1C64A746DC9918D8C5D4DB62C54F0BC55B9DCE075F315571E799C/* Not supported: data(82 00 C8 3A 00 E7 82 1A 00 F4 B8 4C 0C 00 F9 D6 82 2B 06 00 FC E8 AD 57 18 03 00 FD F1 CB 83 38 0E 02 00 FE F6 DD A7 5E 23 08 01 00 FE F9 E8 C1 82 41 17 05 01 00 FF FB EF D3 A2 63 2D 0F 04 01 00 FF FB F3 DF BA 83 4A 21 0B 03 01 00 FF FC F5 E6 CA 9E 69 39 18 08 02 01 00 FF FD F7 EB D6 B3 84 54 2C 13 07 02 01 00 FF FE FA F0 DF C4 9F 70 45 24 0F 06 02 01 00 FF FE FD F5 E7 D1 B0 88 5D 37 1B 0B 03 02 01 00 FF FE FD FC EF DD C2 9E 75 4C 2A 12 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=5 A95F7F7795C09395F9DE1066B8856EA6953929115CA642CF0A262E565DCC8FBB/* Not supported: data(15 FC 38 2E FF) */; internal static readonly __StaticArrayInitTypeSize=96 A971219F880C6D4B275CB4031E5DADCD52F9C3B49D4574837CF208BB9A71C044/* Not supported: data(BD 00 A8 FD 69 02 67 77 75 00 61 FF D2 FB 08 74 34 00 DD 00 A8 F6 74 6E FC FF 11 02 EA F2 E5 66 D0 FF F6 02 8C F0 A5 5D B0 FF 89 03 75 EF 06 53 9D FF CC 03 82 EF 66 47 95 FF C7 03 8B F0 27 3B 99 FF 80 03 61 F2 AE 2E A5 FF 05 03 CF F4 5E 22 B9 FF 63 02 A1 F7 98 16 D2 FF A9 01 A1 FA B4 0B) */; internal static readonly __StaticArrayInitTypeSize=30 AA5912904B271C8BA2D94B5A1630BA855EA191C24622B6D0BFEB1E7A70C9ED6E/* Not supported: data(AF 94 A0 B0 B2 AD AE A4 B1 AE C4 B6 C6 C0 B6 44 3E 42 3C 48 75 55 5A 76 88 97 8E A0 8E 9B) */; internal static readonly __StaticArrayInitTypeSize=17 AB5BCC817B92178A201EC5744F39ED9123768D8010490A9027EDCAA161C35A6E/* Not supported: data(00 00 02 05 09 0E 14 1B 23 2C 36 41 4D 5A 68 77 87) */; internal static readonly __StaticArrayInitTypeSize=5 AD23D3A172AA3CFBE79C276D39E97AD70D0B9BC81AA89569912809C5EC69530A/* Not supported: data(01 FD 16 45 1F) */; internal static readonly __StaticArrayInitTypeSize=18 ADB25EDDDF7D05226D32E4FFC663FDD85421ACD7F19EB4F81AB0E490147013A1/* Not supported: data(52 4A 4F 5F 6D 80 91 A0 AD CD CD CD E0 FF FF E0 FF E0) */; internal static readonly __StaticArrayInitTypeSize=16 AFFBFFF7981564A1AA7E7C45020B0D77ACA8DEE2384B61212DD702114ACC0C91/* Not supported: data(CD 6C 00 00 00 00 00 00 00 10 00 00 00 20 00 00) */; internal static readonly long B03AA33C255179F15E72CDDB9939B0397F1DA2F33AA56BAE91B75EC7FEC43335/* Not supported: data(00 06 01 02 03 04 05 07) */; internal static readonly __StaticArrayInitTypeSize=76 B28B0E69119ABE1259C728F562538056E2F9C046261952E9F430BE73C2073A4B/* Not supported: data(02 00 00 00 04 00 00 00 06 00 00 00 08 00 00 00 0A 00 00 00 0C 00 00 00 0E 00 00 00 10 00 00 00 14 00 00 00 18 00 00 00 1C 00 00 00 20 00 00 00 28 00 00 00 30 00 00 00 38 00 00 00 44 00 00 00 50 00 00 00 60 00 00 00 78 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 B4DF28769145CF3E3FCD687C411F09BF9AE7F22F4C939B48D2AE1FF8BE4CD2C0/* Not supported: data(FF 04 7C 02 FC) */; internal static readonly __StaticArrayInitTypeSize=32 B5B9A7E7C7211682C0A22C18FE81EA7B257AB8044811FE83EEED6A0435FAB53A/* Not supported: data(5C CA BE D8 B6 DF 9A E2 9C E6 78 EC 7A F4 CC FC 34 03 86 0B 88 13 64 19 66 1D 4A 20 42 27 A4 35) */; internal static readonly __StaticArrayInitTypeSize=5 B5BB9775CDC7168488F332035592E4F23D3EC267A70E797866F68E385DE02DDE/* Not supported: data(02 0D 2A 0D 1F) */; internal static readonly __StaticArrayInitTypeSize=32 B78F849934314F8BB5F9497F8288EBB1A9792AA7374E1D840D8152484B8B980A/* Not supported: data(00 00 00 00 40 1F 00 00 B8 24 00 00 EC 2C 00 00 BC 34 00 00 5C 44 00 00 A8 61 00 00 80 38 01 00) */; internal static readonly __StaticArrayInitTypeSize=34 BB6FBF87B971D2E0160B9C7AA9D3FBDDC2410BDAF1C7E95CDB8DAD073F74CC22/* Not supported: data(00 00 01 FF 00 01 FF 00 FF 01 FE 02 FE FE 02 FD 02 03 FD FC 03 FC 04 04 FB 05 FA FB 06 F9 06 05 08 F7) */; internal static readonly __StaticArrayInitTypeSize=392 BD2B70BE94E04EAA5ED34BC2F5D48938D33571FA92C7EF8028F8CE83214FAB08/* Not supported: data(28 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 28 0F 17 1C 1F 22 24 26 27 29 2A 2B 2C 2D 2E 2F 2F 31 32 33 34 35 36 37 37 39 3A 3B 3C 3D 3E 3F 3F 41 42 43 44 45 46 47 47 28 14 21 29 30 35 39 3D 40 42 45 47 49 4B 4C 4E 50 52 55 57 59 5B 5C 5E 60 62 65 67 69 6B 6C 6E 70 72 75 77 79 7B 7C 7E 80 28 17 27 33 3C 43 49 4F 53 57 5B 5E 61 64 66 69 6B 6F 73 76 79 7C 7E 81 83 87 8B 8E 91 94 96 99 9B 9F A3 A6 A9 AC AE B1 B3 23 1C 31 41 4E 59 63 6B 72 78 7E 84 88 8D 91 95 99 9F A5 AB B0 B4 B9 BD C0 C7 CD D3 D8 DC E1 E5 E8 EF F5 FB 15 21 3A 4F 61 70 7D 89 94 9D A6 AE B6 BD C3 C9 CF D9 E3 EB F3 FB 11 23 3F 56 6A 7B 8B 98 A5 B1 BB C5 CE D6 DE E6 ED FA 19 1F 37 4B 5B 69 75 80 8A 92 9A A1 A8 AE B4 B9 BE C8 D0 D7 DE E5 EB F0 F5 FF 10 24 41 59 6E 80 90 9F AD B9 C4 CF D9 E2 EA F2 FA 0B 29 4A 67 80 97 AC BF D1 E1 F1 FF 09 2B 4F 6E 8A A3 BA CF E3 F6 0C 27 47 63 7B 90 A4 B6 C6 D6 E4 F1 FD 09 2C 51 71 8E A8 C0 D6 EB FF 07 31 5A 7F A0 BF DC F7 06 33 5F 86 AA CB EA 07 2F 57 7B 9B B8 D4 ED 06 34 61 89 AE D0 F0 05 39 6A 97 C0 E7 05 3B 6F 9E CA F3 05 37 67 93 BB E0 05 3C 71 A1 CE F8 04 41 7A AF E0 04 43 7F B6 EA) */; internal static readonly long BD55CF1C01F8EAB00163AEEB9E289E0778FB5CE27191C5A5D1927B4F4D04C5C7/* Not supported: data(47 38 2B 1E 15 0C 06 00) */; internal static readonly __StaticArrayInitTypeSize=480 BD833B97BFE31E363672A252CC34EE76646BCB18E4ACB0C4531EDF8F26B1A5CC/* Not supported: data(02 00 00 00 14 00 00 00 37 00 00 00 6C 00 00 00 B2 00 00 00 0A 01 00 00 74 01 00 00 EE 01 00 00 7B 02 00 00 18 03 00 00 C6 03 00 00 85 04 00 00 55 05 00 00 36 06 00 00 27 07 00 00 29 08 00 00 3A 09 00 00 5B 0A 00 00 8C 0B 00 00 CC 0C 00 00 1B 0E 00 00 79 0F 00 00 E5 10 00 00 5F 12 00 00 E6 13 00 00 7B 15 00 00 1C 17 00 00 CA 18 00 00 84 1A 00 00 49 1C 00 00 19 1E 00 00 F3 1F 00 00 D7 21 00 00 C4 23 00 00 B9 25 00 00 B7 27 00 00 BC 29 00 00 C7 2B 00 00 D8 2D 00 00 EF 2F 00 00 0A 32 00 00 29 34 00 00 4B 36 00 00 6F 38 00 00 95 3A 00 00 BB 3C 00 00 E2 3E 00 00 08 41 00 00 2D 43 00 00 50 45 00 00 6F 47 00 00 8B 49 00 00 A3 4B 00 00 B5 4D 00 00 C2 4F 00 00 C8 51 00 00 C7 53 00 00 BE 55 00 00 AD 57 00 00 93 59 00 00 6F 5B 00 00 42 5D 00 00 0A 5F 00 00 C6 60 00 00 78 62 00 00 1D 64 00 00 B7 65 00 00 43 67 00 00 C3 68 00 00 36 6A 00 00 9C 6B 00 00 F5 6C 00 00 40 6E 00 00 7D 6F 00 00 AD 70 00 00 CF 71 00 00 E3 72 00 00 EA 73 00 00 E4 74 00 00 D0 75 00 00 B0 76 00 00 82 77 00 00 48 78 00 00 01 79 00 00 AF 79 00 00 51 7A 00 00 E7 7A 00 00 72 7B 00 00 F3 7B 00 00 69 7C 00 00 D6 7C 00 00 39 7D 00 00 94 7D 00 00 E5 7D 00 00 2F 7E 00 00 72 7E 00 00 AD 7E 00 00 E1 7E 00 00 10 7F 00 00 38 7F 00 00 5C 7F 00 00 7A 7F 00 00 95 7F 00 00 AB 7F 00 00 BD 7F 00 00 CD 7F 00 00 D9 7F 00 00 E4 7F 00 00 EC 7F 00 00 F2 7F 00 00 F6 7F 00 00 FA 7F 00 00 FC 7F 00 00 FE 7F 00 00 FF 7F 00 00 FF 7F 00 00 FF 7F 00 00 FF 7F 00 00 FF 7F 00 00 FF 7F 00 00) */; internal static readonly __StaticArrayInitTypeSize=12 BE13366EC772203E8827F02633A735B989DDDA90CF8F61D69A59C14B36EDD8A9/* Not supported: data(75 52 82 0C 59 9A 04 19 75 52 82 0C) */; internal static readonly __StaticArrayInitTypeSize=12 BE30EB9DCE75FCAFA41BECF699516D60818B04A7A429B6000018A8782A3AB7D9/* Not supported: data(00 01 00 01 FF 02 FF 02 FE 03 FE 03) */; internal static readonly __StaticArrayInitTypeSize=5 BECB2A5C86C112F97D58FA5B035C84DA2ADFC11E60ADE1C40ECEC319FF36A820/* Not supported: data(F0 46 53 EB 0B) */; internal static readonly long BF5B15E78422D311EF7F024B0592858600EB4072A94860BCD4E9B35D78BE0065/* Not supported: data(2E 02 5A 57 5D 5B 52 62) */; internal static readonly __StaticArrayInitTypeSize=10 BF761FFF4D386D368C9EC29069BD296B0FAE55ECE5205C0A76601E5178110AC1/* Not supported: data(00 09 06 03 04 05 08 01 02 07) */; internal static readonly __StaticArrayInitTypeSize=32 C1A53A51A0A1421638B4AAC46417D4249AFED33DB1718C50A3AD207A71ABBFC1/* Not supported: data(E0 2E 00 00 E8 03 00 00 98 3A 00 00 E8 03 00 00 50 46 00 00 D0 07 00 00 F0 55 00 00 D0 07 00 00) */; internal static readonly __StaticArrayInitTypeSize=320 C1E7DFC4310B65B031595F11EADA52CD36941022D16BC7E0A4FB38CEE9C054CD/* Not supported: data(0C 23 3C 53 6C 84 9D B4 CE E4 0F 20 37 4D 65 7D 97 AF C9 E1 13 2A 42 59 72 89 A2 B8 D1 E6 0C 19 32 48 61 78 93 AC C8 DF 1A 2C 45 5A 72 87 9F B4 CD E1 0D 16 35 50 6A 82 9C B4 CD E4 0F 19 2C 40 5A 73 8E A8 C4 DE 13 18 3E 52 64 78 91 A8 BE D6 16 1F 32 4F 67 78 97 AA CB E3 15 1D 2D 41 6A 7C 96 AB C4 E0 1E 31 4B 61 79 8E A5 BA D1 E5 13 19 34 46 5D 74 8F A6 C0 DB 1A 22 3E 4B 61 76 91 A7 C2 D9 19 21 38 46 5B 71 8F A5 C4 DF 15 22 33 48 61 75 91 AB C4 DE 14 1D 32 43 5A 75 90 A8 C5 DD 16 1F 30 42 5F 75 92 A8 C4 DE 18 21 33 4D 74 86 9E B4 C8 E0 15 1C 46 57 6A 7C 95 AA C2 D9 1A 21 35 40 53 75 98 AD CC E1 1B 22 41 5F 6C 81 9B AE D2 E1 14 1A 48 63 71 83 9A B0 C8 DB 22 2B 3D 4E 5D 72 9B B1 CD E5 17 1D 36 61 7C 8A A3 B3 D1 E5 1E 26 38 59 76 81 9E B2 C8 E7 15 1D 31 3F 55 6F 8E A3 C1 DE 1B 30 4D 67 85 9E B3 C4 D7 E8 1D 2F 4A 63 7C 97 B0 C6 DC ED 21 2A 3D 4C 5D 79 9B AE CF E1 1D 35 57 70 88 9A AA BC D0 E3 18 1E 34 54 83 96 A6 BA CB E5 25 30 40 54 68 76 9C B1 C9 E6) */; internal static readonly long C279AF3C125F26917B3D0EB08DDD09832F74267CEB1E1FB5B1464BF4B2C1B1DB/* Not supported: data(00 FE 00 FD 02 00 01 FF) */; internal static readonly __StaticArrayInitTypeSize=34 C2BEF4372923C0EC9155544B2D13A58A72FF6339B0C54F5A8481868D5D04493E/* Not supported: data(00 00 01 00 00 00 00 00 00 00 FF 01 00 00 01 FF 00 01 FF FF 01 FF 02 01 FF 02 FE FE 02 FE 02 02 03 FD) */; internal static readonly __StaticArrayInitTypeSize=6 C3BDCCF6C5F32FA708F708CB9A76AB7753D100AF622F45D7348F07724F7F6FFC/* Not supported: data(CD 3C 00 30 00 20) */; internal static readonly __StaticArrayInitTypeSize=5 C4200692FF638DC72E1B732420F55DDBD6A0C2DC6425D3918354D58D6617D6C0/* Not supported: data(F9 41 58 F7 F2) */; internal static readonly __StaticArrayInitTypeSize=32 C4B5405E7778D4A1CF41DB113B73956453E81E7C117303630A0D1E510820DB2B/* Not supported: data(F1 E1 D3 C7 BB AF A4 99 8E 84 7B 72 69 60 58 50 48 40 39 32 2C 26 21 1D 18 14 10 0C 09 05 02 00) */; internal static readonly __StaticArrayInitTypeSize=5 C5EFF61D3E285CCAC1454B74A6B1F582D57BD8EFD57A4B26DA351B869B83EB0F/* Not supported: data(F3 DD C0 B5 00) */; internal static readonly long C694D0F3C1F2048A0C444FD194D05C25F171B93380915016C90EE4FB66E1694E/* Not supported: data(E0 C0 A0 80 60 40 20 00) */; internal static readonly __StaticArrayInitTypeSize=40 C830E6FB05DC874D6F660AAE062DFC2772BE96ABE74FF735DCFBA1CC0EC2EAEC/* Not supported: data(E6 3E C6 C4 F3 FF 00 00 14 00 1A 00 05 00 E1 FF D5 FF FC FF 41 00 5A 00 07 00 63 FF 08 FF D4 FF 51 02 2F 06 34 0A C7 0C) */; internal static readonly __StaticArrayInitTypeSize=512 C9E5928EC04D8A85F16EED8692C24F5E52FA0FB85EEB1DB3EC6326F1F17F1DFC/* Not supported: data(00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E 00 00 80 3E D0 25 B4 3E 97 39 AD 3E 09 A5 9F 3E FA ED 8B 3E CD AC 65 3E F8 A9 2A 3E 34 30 D2 3D 5A F1 0D 3D 5A F1 0D BD 34 30 D2 BD F8 A9 2A BE CD AC 65 BE FA ED 8B BE 09 A5 9F BE 97 39 AD BE D0 25 B4 BE 87 8A B1 3E 1B 83 96 3E 60 23 49 3E C4 42 8D 3D C4 42 8D BD 60 23 49 BE 1B 83 96 BE 87 8A B1 BE 87 8A B1 BE 1B 83 96 BE 60 23 49 BE C4 42 8D BD C4 42 8D 3D 60 23 49 3E 1B 83 96 3E 87 8A B1 3E 97 39 AD 3E CD AC 65 3E 5A F1 0D 3D F8 A9 2A BE 09 A5 9F BE D0 25 B4 BE FA ED 8B BE 34 30 D2 BD 34 30 D2 3D FA ED 8B 3E D0 25 B4 3E 09 A5 9F 3E F8 A9 2A 3E 5A F1 0D BD CD AC 65 BE 97 39 AD BE 7D 3D A7 3E D2 8B 0A 3E D2 8B 0A BE 7D 3D A7 BE 7D 3D A7 BE D2 8B 0A BE D2 8B 0A 3E 7D 3D A7 3E 7D 3D A7 3E D2 8B 0A 3E D2 8B 0A BE 7D 3D A7 BE 7D 3D A7 BE D2 8B 0A BE D2 8B 0A 3E 7D 3D A7 3E 09 A5 9F 3E 5A F1 0D 3D FA ED 8B BE 97 39 AD BE 34 30 D2 BD CD AC 65 3E D0 25 B4 3E F8 A9 2A 3E F8 A9 2A BE D0 25 B4 BE CD AC 65 BE 34 30 D2 3D 97 39 AD 3E FA ED 8B 3E 5A F1 0D BD 09 A5 9F BE 1B 83 96 3E C4 42 8D BD 87 8A B1 BE 60 23 49 BE 60 23 49 3E 87 8A B1 3E C4 42 8D 3D 1B 83 96 BE 1B 83 96 BE C4 42 8D 3D 87 8A B1 3E 60 23 49 3E 60 23 49 BE 87 8A B1 BE C4 42 8D BD 1B 83 96 3E FA ED 8B 3E F8 A9 2A BE 97 39 AD BE 5A F1 0D 3D D0 25 B4 3E 34 30 D2 3D 09 A5 9F BE CD AC 65 BE CD AC 65 3E 09 A5 9F 3E 34 30 D2 BD D0 25 B4 BE 5A F1 0D BD 97 39 AD 3E F8 A9 2A 3E FA ED 8B BE) */; internal static readonly __StaticArrayInitTypeSize=3600 CAE22E5054755A1EDF59DB7F23D403252B13F581A9F3CD53D4D73E284C9418B9/* Not supported: data(FF 7F FF 7F FF 7F FE 7F FD 7F FB 7F F9 7F F7 7F F4 7F F1 7F EE 7F EA 7F E6 7F E2 7F DD 7F D8 7F D2 7F CD 7F C6 7F C0 7F B9 7F B2 7F AA 7F A2 7F 9A 7F 91 7F 88 7F 7F 7F 75 7F 6B 7F 61 7F 56 7F 4B 7F 40 7F 34 7F 28 7F 1B 7F 0E 7F 01 7F F4 7E E6 7E D8 7E C9 7E BA 7E AB 7E 9B 7E 8B 7E 7B 7E 6A 7E 59 7E 48 7E 36 7E 24 7E 12 7E FF 7D EC 7D D9 7D C5 7D B1 7D 9D 7D 88 7D 73 7D 5D 7D 47 7D 31 7D 1B 7D 04 7D ED 7C D5 7C BD 7C A5 7C 8C 7C 73 7C 5A 7C 41 7C 27 7C 0C 7C F2 7B D7 7B BC 7B A0 7B 84 7B 68 7B 4B 7B 2E 7B 11 7B F3 7A D5 7A B7 7A 98 7A 79 7A 5A 7A 3A 7A 1A 7A FA 79 D9 79 B8 79 97 79 75 79 53 79 31 79 0E 79 EB 78 C8 78 A4 78 80 78 5C 78 37 78 12 78 ED 77 C7 77 A1 77 7B 77 54 77 2D 77 06 77 DE 76 B6 76 8E 76 65 76 3D 76 13 76 EA 75 C0 75 96 75 6B 75 40 75 15 75 EA 74 BE 74 92 74 65 74 38 74 0B 74 DE 73 B0 73 82 73 54 73 25 73 F6 72 C7 72 97 72 67 72 37 72 06 72 D6 71 A4 71 73 71 41 71 0F 71 DC 70 AA 70 77 70 43 70 10 70 DC 6F A7 6F 73 6F 3E 6F 09 6F D3 6E 9D 6E 67 6E 31 6E FA 6D C3 6D 8C 6D 54 6D 1C 6D E4 6C AC 6C 73 6C 3A 6C 00 6C C7 6B 8D 6B 52 6B 18 6B DD 6A A2 6A 66 6A 2A 6A EE 69 B2 69 75 69 38 69 FB 68 BE 68 80 68 42 68 04 68 C5 67 86 67 47 67 07 67 C8 66 87 66 47 66 07 66 C6 65 84 65 43 65 01 65 BF 64 7D 64 3A 64 F8 63 B4 63 71 63 2D 63 EA 62 A5 62 61 62 1C 62 D7 61 92 61 4C 61 06 61 C0 60 7A 60 33 60 ED 5F A5 5F 5E 5F 16 5F CE 5E 86 5E 3E 5E F5 5D AC 5D 63 5D 1A 5D D0 5C 86 5C 3C 5C F1 5B A6 5B 5B 5B 10 5B C5 5A 79 5A 2D 5A E1 59 94 59 48 59 FB 58 AD 58 60 58 12 58 C4 57 76 57 28 57 D9 56 8A 56 3B 56 EC 55 9C 55 4C 55 FC 54 AC 54 5B 54 0B 54 BA 53 68 53 17 53 C5 52 73 52 21 52 CF 51 7C 51 29 51 D6 50 83 50 30 50 DC 4F 88 4F 34 4F E0 4E 8B 4E 36 4E E1 4D 8C 4D 37 4D E1 4C 8B 4C 35 4C DF 4B 88 4B 32 4B DB 4A 84 4A 2C 4A D5 49 7D 49 25 49 CD 48 75 48 1C 48 C4 47 6B 47 12 47 B8 46 5F 46 05 46 AB 45 51 45 F7 44 9D 44 42 44 E7 43 8C 43 31 43 D6 42 7A 42 1F 42 C3 41 67 41 0A 41 AE 40 51 40 F4 3F 97 3F 3A 3F DD 3E 7F 3E 22 3E C4 3D 66 3D 08 3D A9 3C 4B 3C EC 3B 8D 3B 2E 3B CF 3A 70 3A 10 3A B1 39 51 39 F1 38 91 38 31 38 D0 37 70 37 0F 37 AE 36 4D 36 EC 35 8A 35 29 35 C7 34 66 34 04 34 A2 33 3F 33 DD 32 7B 32 18 32 B5 31 52 31 EF 30 8C 30 29 30 C6 2F 62 2F FE 2E 9A 2E 37 2E D2 2D 6E 2D 0A 2D A6 2C 41 2C DC 2B 78 2B 13 2B AE 2A 48 2A E3 29 7E 29 18 29 B3 28 4D 28 E7 27 81 27 1B 27 B5 26 4F 26 E8 25 82 25 1B 25 B5 24 4E 24 E7 23 80 23 19 23 B2 22 4A 22 E3 21 7C 21 14 21 AC 20 45 20 DD 1F 75 1F 0D 1F A5 1E 3D 1E D5 1D 6C 1D 04 1D 9B 1C 33 1C CA 1B 61 1B F9 1A 90 1A 27 1A BE 19 55 19 EC 18 82 18 19 18 B0 17 46 17 DD 16 73 16 0A 16 A0 15 36 15 CD 14 63 14 F9 13 8F 13 25 13 BB 12 51 12 E7 11 7C 11 12 11 A8 10 3D 10 D3 0F 69 0F FE 0E 94 0E 29 0E BE 0D 54 0D E9 0C 7E 0C 14 0C A9 0B 3E 0B D3 0A 68 0A FE 09 93 09 28 09 BD 08 52 08 E7 07 7C 07 11 07 A6 06 3A 06 CF 05 64 05 F9 04 8E 04 23 04 B8 03 4C 03 E1 02 76 02 0B 02 A0 01 34 01 C9 00 5E 00 F3 FF 87 FF 1C FF B1 FE 46 FE DA FD 6F FD 04 FD 99 FC 2E FC C2 FB 57 FB EC FA 81 FA 16 FA AB F9 40 F9 D5 F8 6A F8 FF F7 93 F7 29 F7 BE F6 53 F6 E8 F5 7D F5 12 F5 A7 F4 3C F4 D2 F3 67 F3 FC F2 91 F2 27 F2 BC F1 52 F1 E7 F0 7D F0 12 F0 A8 EF 3E EF D3 EE 69 EE FF ED 95 ED 2B ED C1 EC 57 EC ED EB 83 EB 19 EB AF EA 46 EA DC E9 72 E9 09 E9 9F E8 36 E8 CD E7 63 E7 FA E6 91 E6 28 E6 BF E5 56 E5 ED E4 84 E4 1C E4 B3 E3 4B E3 E2 E2 7A E2 11 E2 A9 E1 41 E1 D9 E0 71 E0 09 E0 A1 DF 3A DF D2 DE 6B DE 03 DE 9C DD 35 DD CD DC 66 DC FF DB 99 DB 32 DB CB DA 65 DA FE D9 98 D9 32 D9 CB D8 65 D8 FF D7 9A D7 34 D7 CE D6 69 D6 04 D6 9E D5 39 D5 D4 D4 6F D4 0B D4 A6 D3 41 D3 DD D2 79 D2 14 D2 B0 D1 4D D1 E9 D0 85 D0 22 D0 BE CF 5B CF F8 CE 95 CE 32 CE CF CD 6D CD 0A CD A8 CC 46 CC E4 CB 82 CB 20 CB BF CA 5D CA FC C9 9B C9 3A C9 D9 C8 78 C8 18 C8 B7 C7 57 C7 F7 C6 97 C6 37 C6 D8 C5 78 C5 19 C5 BA C4 5B C4 FC C3 9D C3 3F C3 E1 C2 83 C2 25 C2 C7 C1 69 C1 0C C1 AE C0 51 C0 F4 BF 98 BF 3B BF DF BE 82 BE 26 BE CB BD 6F BD 13 BD B8 BC 5D BC 02 BC A7 BB 4D BB F2 BA 98 BA 3E BA E4 B9 8B B9 31 B9 D8 B8 7F B8 26 B8 CD B7 75 B7 1D B7 C5 B6 6D B6 15 B6 BE B5 66 B5 0F B5 B9 B4 62 B4 0C B4 B5 B3 5F B3 0A B3 B4 B2 5F B2 09 B2 B5 B1 60 B1 0B B1 B7 B0 63 B0 0F B0 BB AF 68 AF 15 AF C2 AE 6F AE 1D AE CA AD 78 AD 26 AD D5 AC 83 AC 32 AC E1 AB 90 AB 40 AB F0 AA A0 AA 50 AA 00 AA B1 A9 62 A9 13 A9 C5 A8 76 A8 28 A8 DA A7 8D A7 3F A7 F2 A6 A5 A6 59 A6 0C A6 C0 A5 74 A5 28 A5 DD A4 92 A4 47 A4 FC A3 B2 A3 68 A3 1E A3 D4 A2 8B A2 42 A2 F9 A1 B0 A1 68 A1 20 A1 D8 A0 90 A0 49 A0 02 A0 BB 9F 74 9F 2E 9F E8 9E A2 9E 5D 9E 18 9E D3 9D 8E 9D 4A 9D 05 9D C2 9C 7E 9C 3B 9C F8 9B B5 9B 72 9B 30 9B EE 9A AD 9A 6B 9A 2A 9A E9 99 A9 99 68 99 29 99 E9 98 A9 98 6A 98 2B 98 ED 97 AF 97 71 97 33 97 F5 96 B8 96 7B 96 3F 96 03 96 C7 95 8B 95 50 95 14 95 DA 94 9F 94 65 94 2B 94 F1 93 B8 93 7F 93 46 93 0E 93 D6 92 9E 92 66 92 2F 92 F8 91 C1 91 8B 91 55 91 1F 91 EA 90 B5 90 80 90 4C 90 17 90 E3 8F B0 8F 7D 8F 4A 8F 17 8F E5 8E B2 8E 81 8E 4F 8E 1E 8E ED 8D BD 8D 8D 8D 5D 8D 2D 8D FE 8C CF 8C A1 8C 72 8C 44 8C 17 8C E9 8B BC 8B 90 8B 63 8B 37 8B 0B 8B E0 8A B5 8A 8A 8A 60 8A 36 8A 0C 8A E2 89 B9 89 90 89 68 89 40 89 18 89 F0 88 C9 88 A2 88 7C 88 55 88 30 88 0A 88 E5 87 C0 87 9B 87 77 87 53 87 2F 87 0C 87 E9 86 C7 86 A4 86 82 86 61 86 40 86 1F 86 FE 85 DE 85 BE 85 9E 85 7F 85 60 85 42 85 23 85 05 85 E8 84 CB 84 AE 84 91 84 75 84 59 84 3E 84 22 84 07 84 ED 83 D3 83 B9 83 9F 83 86 83 6D 83 55 83 3D 83 25 83 0E 83 F6 82 E0 82 C9 82 B3 82 9D 82 88 82 73 82 5E 82 4A 82 36 82 22 82 0F 82 FC 81 E9 81 D7 81 C5 81 B3 81 A2 81 91 81 81 81 71 81 61 81 51 81 42 81 33 81 25 81 17 81 09 81 FB 80 EE 80 E2 80 D5 80 C9 80 BD 80 B2 80 A7 80 9C 80 92 80 88 80 7F 80 75 80 6D 80 64 80 5C 80 54 80 4C 80 45 80 3E 80 38 80 32 80 2C 80 27 80 22 80 1D 80 19 80 15 80 11 80 0E 80 0B 80 08 80 06 80 04 80 03 80 01 80 01 80 01 80 FF 7F FF 7F FD 7F F9 7F F4 7F EE 7F E6 7F DC 7F D2 7F C6 7F B8 7F A9 7F 99 7F 87 7F 74 7F 60 7F 4A 7F 32 7F 1A 7F 00 7F E4 7E C7 7E A9 7E 89 7E 68 7E 46 7E 22 7E FD 7D D6 7D AE 7D 85 7D 5A 7D 2E 7D 01 7D D2 7C A2 7C 70 7C 3D 7C 09 7C D4 7B 9D 7B 64 7B 2A 7B EF 7A B3 7A 75 7A 36 7A F6 79 B4 79 71 79 2C 79 E7 78 A0 78 57 78 0D 78 C2 77 76 77 28 77 D9 76 89 76 37 76 E5 75 90 75 3B 75 E4 74 8C 74 33 74 D8 73 7C 73 1F 73 C1 72 61 72 00 72 9E 71 3B 71 D6 70 70 70 09 70 A1 6F 37 6F CD 6E 61 6E F3 6D 85 6D 15 6D A4 6C 32 6C BF 6B 4B 6B D5 6A 5F 6A E7 69 6E 69 F4 68 78 68 FC 67 7E 67 FF 66 7F 66 FE 65 7C 65 F9 64 75 64 EF 63 69 63 E1 62 58 62 CE 61 44 61 B8 60 2B 60 9D 5F 0D 5F 7D 5E EC 5D 5A 5D C7 5C 32 5C 9D 5B 07 5B 70 5A D7 59 3E 59 A4 58 09 58 6C 57 CF 56 31 56 92 55 F2 54 51 54 AF 53 0D 53 69 52 C5 51 1F 51 79 50 D2 4F 29 4F 80 4E D7 4D 2C 4D 80 4C D4 4B 27 4B 79 4A CA 49 1A 49 6A 48 B9 47 07 47 54 46 A0 45 EC 44 37 44 81 43 CA 42 13 42 5B 41 A2 40 E9 3F 2F 3F 74 3E B8 3D FC 3C 3F 3C 82 3B C3 3A 04 3A 45 39 85 38 C4 37 03 37 41 36 7E 35 BB 34 F7 33 33 33 6E 32 A9 31 E3 30 1D 30 56 2F 8E 2E C6 2D FD 2C 34 2C 6B 2B A1 2A D6 29 0C 29 40 28 74 27 A8 26 DB 25 0E 25 41 24 73 23 A5 22 D6 21 07 21 38 20 68 1F 98 1E C7 1D F7 1C 26 1C 54 1B 83 1A B1 19 DE 18 0C 18 39 17 66 16 93 15 BF 14 EC 13 18 13 43 12 6F 11 9B 10 C6 0F F1 0E 1C 0E 47 0D 71 0C 9C 0B C6 0A F0 09 1A 09 44 08 6E 07 98 06 C2 05 EC 04 15 04 3F 03 69 02 92 01 BC 00 E5 FF 0F FF 38 FE 62 FD 8B FC B5 FB DF FA 08 FA 32 F9 5C F8 86 F7 B0 F6 DA F5 05 F5 2F F4 59 F3 84 F2 AF F1 DA F0 05 F0 30 EF 5C EE 88 ED B3 EC DF EB 0C EB 38 EA 65 E9 92 E8 BF E7 ED E6 1B E6 49 E5 77 E4 A6 E3 D5 E2 04 E2 34 E1 64 E0 94 DF C5 DE F6 DD 28 DD 59 DC 8C DB BE DA F1 D9 25 D9 59 D8 8D D7 C2 D6 F7 D5 2D D5 63 D4 99 D3 D0 D2 08 D2 40 D1 79 D0 B2 CF EB CE 26 CE 60 CD 9C CC D8 CB 14 CB 51 CA 8F C9 CD C8 0C C8 4B C7 8B C6 CC C5 0D C5 4F C4 92 C3 D5 C2 19 C2 5D C1 A3 C0 E9 BF 2F BF 77 BE BF BD 08 BD 52 BC 9C BB E7 BA 33 BA 7F B9 CD B8 1B B8 6A B7 BA B6 0A B6 5C B5 AE B4 01 B4 55 B3 A9 B2 FF B1 55 B1 AC B0 05 B0 5E AF B7 AE 12 AE 6E AD CB AC 28 AC 86 AB E6 AA 46 AA A7 A9 09 A9 6C A8 D1 A7 36 A7 9C A6 03 A6 6B A5 D4 A4 3E A4 A8 A3 14 A3 81 A2 F0 A1 5F A1 CF A0 40 A0 B2 9F 25 9F 9A 9E 0F 9E 85 9D FD 9C 76 9C EF 9B 6A 9B E6 9A 63 9A E1 99 60 99 E1 98 62 98 E5 97 69 97 EE 96 74 96 FB 95 84 95 0D 95 98 94 24 94 B1 93 3F 93 CF 92 5F 92 F1 91 84 91 19 91 AE 90 45 90 DD 8F 76 8F 11 8F AC 8E 49 8E E7 8D 87 8D 27 8D C9 8C 6D 8C 11 8C B7 8B 5E 8B 06 8B B0 8A 5A 8A 07 8A B4 89 63 89 13 89 C4 88 77 88 2B 88 E0 87 97 87 4F 87 08 87 C2 86 7E 86 3C 86 FA 85 BA 85 7B 85 3E 85 02 85 C7 84 8E 84 56 84 1F 84 EA 83 B6 83 83 83 52 83 22 83 F4 82 C6 82 9B 82 70 82 47 82 20 82 FA 81 D5 81 B1 81 8F 81 6F 81 4F 81 31 81 15 81 FA 80 E0 80 C8 80 B1 80 9B 80 87 80 74 80 63 80 53 80 44 80 37 80 2C 80 21 80 18 80 11 80 0B 80 06 80 02 80 01 80 FF 7F FC 7F F3 7F E5 7F D0 7F B6 7F 97 7F 72 7F 47 7F 17 7F E1 7E A5 7E 64 7E 1E 7E D1 7D 80 7D 29 7D CC 7C 6A 7C 03 7C 96 7B 23 7B AB 7A 2E 7A AC 79 24 79 97 78 04 78 6C 77 CF 76 2D 76 86 75 D9 74 28 74 71 73 B5 72 F4 71 2E 71 63 70 94 6F BF 6E E6 6D 07 6D 24 6C 3C 6B 50 6A 5F 69 69 68 6E 67 6F 66 6C 65 64 64 58 63 47 62 32 61 19 60 FB 5E DA 5D B4 5C 8A 5B 5D 5A 2B 59 F5 57 BC 56 7E 55 3D 54 F8 52 B0 51 64 50 14 4F C1 4D 6B 4C 11 4B B4 49 54 48 F0 46 8A 45 20 44 B3 42 44 41 D2 3F 5C 3E E4 3C 6A 3B ED 39 6D 38 EB 36 66 35 DF 33 56 32 CA 30 3D 2F AD 2D 1B 2C 88 2A F2 28 5B 27 C2 25 27 24 8B 22 ED 20 4E 1F AD 1D 0C 1C 68 1A C4 18 1F 17 78 15 D1 13 29 12 80 10 D6 0E 2C 0D 81 0B D5 09 2A 08 7D 06 D1 04 24 03 77 01 CA FF 1D FE 71 FC C4 FA 18 F9 6B F7 C0 F5 14 F4 69 F2 BF F0 16 EF 6D ED C5 EB 1E EA 78 E8 D3 E6 2F E5 8C E3 EA E1 4A E0 AB DE 0E DD 72 DB D8 D9 3F D8 A8 D6 13 D5 80 D3 EF D1 60 D0 D3 CE 48 CD BF CB 39 CA B5 C8 33 C7 B4 C5 37 C4 BD C2 46 C1 D2 BF 60 BE F1 BC 85 BB 1C BA B7 B8 54 B7 F4 B5 98 B4 3F B3 EA B1 97 B0 49 AF FE AD B6 AC 72 AB 32 AA F6 A8 BD A7 88 A6 58 A5 2B A4 02 A3 DD A1 BD A0 A0 9F 88 9E 74 9D 65 9C 5A 9B 53 9A 50 99 53 98 59 97 65 96 75 95 89 94 A3 93 C1 92 E4 91 0B 91 38 90 69 8F A0 8E DB 8D 1C 8D 61 8C AC 8B FB 8A 50 8A AA 89 09 89 6D 88 D7 87 46 87 BA 86 33 86 B2 85 36 85 C0 84 4F 84 E3 83 7D 83 1C 83 C1 82 6B 82 1B 82 D0 81 8B 81 4B 81 11 81 DD 80 AE 80 85 80 61 80 43 80 2A 80 17 80 0A 80 02 80 FF 7F F2 7F CD 7F 92 7F 41 7F D9 7E 5C 7E C8 7D 1D 7D 5D 7C 88 7B 9C 7A 9B 79 85 78 59 77 18 76 C3 74 5A 73 DC 71 4A 70 A4 6E EB 6C 1F 6B 40 69 4F 67 4B 65 36 63 0F 61 D7 5E 8F 5C 37 5A CE 57 56 55 CF 52 3A 50 97 4D E6 4A 28 48 5D 45 86 42 A3 3F B5 3C BD 39 BA 36 AE 33 99 30 7B 2D 55 2A 28 27 F4 23 B9 20 79 1D 34 1A EA 16 9C 13 4B 10 F7 0C A0 09 48 06 EF 02 95 FF 3B FC E2 F8 8A F5 34 F2 E1 EE 90 EB 43 E8 FA E4 B6 E1 77 DE 3F DB 0C D8 E1 D4 BD D1 A1 CE 8E CB 84 C8 84 C5 8E C2 A3 BF C3 BC EF B9 28 B7 6D B4 BF B1 1F AF 8D AC 0A AA 96 A7 32 A5 DD A2 99 A0 66 9E 43 9C 32 9A 33 98 46 96 6C 94 A5 92 F1 90 50 8F C3 8D 4A 8C E5 8A 95 89 5A 88 34 87 23 86 27 85 41 84 71 83 B6 82 11 82 83 81 0B 81 A8 80 5D 80 27 80 09 80) */; internal static readonly __StaticArrayInitTypeSize=16 CB09798CAEE6FD01C1114FA7403C25C3A28362739C9F726AAB7B8BDCB9F6FF23/* Not supported: data(6D 78 76 0C 71 73 75 77 63 3B 57 6F 3F 6F 70 50) */; internal static readonly __StaticArrayInitTypeSize=288 CC757C97FD0CA54AA5EAD86EFDA6D916D6BE101F64E3E6747E0451765F4FE177/* Not supported: data(B9 A6 A3 90 22 DA EF 3F 00 00 00 00 00 00 F0 3F B9 A6 A3 90 22 DA EF 3F 85 0B 16 DA 7B 69 EF 3F 44 46 CD 78 D7 B0 EE 3F 26 53 C3 86 C0 B4 ED 3F 33 DA 2E 5D 56 7B EC 3F A9 CE 17 39 13 0C EB 3F A9 EA 71 21 87 6F E9 3F 72 E6 91 1E 0A AF E7 3F D6 D1 69 C4 69 D4 E5 3F C0 A7 A4 14 95 E9 E3 3F 39 A0 00 E5 4A F8 E1 3F EA 83 1B DF CD 09 E0 3F 55 6A D5 32 42 4D DC 3F 43 5D DE FB 9F AC D8 3F 0F 5A F6 C1 85 3E D5 3F 1F 05 DB CA 43 0D D2 3F A0 67 37 23 18 41 CE 3F 8C 8B 7A F3 E1 FA C8 3F F0 AE 48 86 FB 4C C4 3F 74 E3 27 1F CC 37 C0 3F EE 61 8A CD 22 6F B9 3F 3B 4E 55 CA 00 8A B3 3F E8 61 2E CA E8 57 AD 3F 24 33 CD 2A 22 79 A5 3F BB 69 6D F9 CC 82 9E 3F 22 2C 74 6F 8F EF 94 3F 3E 11 DD 16 D9 8C 8B 3F 5D C2 5F 9B A6 32 81 3F 50 08 B2 D8 05 07 74 3F 81 C8 2A BE 04 1B 65 3F DC EE AB 93 AF DB 52 3F 1B CA 9A A2 6D 46 37 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=18 CD25FA7FA2FB2C68F8C1E127E21A58B22CE8EB5D508CE7BD9D8C920A47392E6D/* Not supported: data(FF E0 C0 96 78 65 5C 59 5D 66 76 86 A0 B6 C0 E0 E0 E0) */; internal static readonly __StaticArrayInitTypeSize=240 CDA8571C4958461E05CA877DAB211147A8DD7CCB19515FF2B025DB7D47DA9724/* Not supported: data(00 00 18 00 30 00 48 00 60 00 08 00 20 00 38 00 50 00 68 00 10 00 28 00 40 00 58 00 70 00 04 00 1C 00 34 00 4C 00 64 00 0C 00 24 00 3C 00 54 00 6C 00 14 00 2C 00 44 00 5C 00 74 00 01 00 19 00 31 00 49 00 61 00 09 00 21 00 39 00 51 00 69 00 11 00 29 00 41 00 59 00 71 00 05 00 1D 00 35 00 4D 00 65 00 0D 00 25 00 3D 00 55 00 6D 00 15 00 2D 00 45 00 5D 00 75 00 02 00 1A 00 32 00 4A 00 62 00 0A 00 22 00 3A 00 52 00 6A 00 12 00 2A 00 42 00 5A 00 72 00 06 00 1E 00 36 00 4E 00 66 00 0E 00 26 00 3E 00 56 00 6E 00 16 00 2E 00 46 00 5E 00 76 00 03 00 1B 00 33 00 4B 00 63 00 0B 00 23 00 3B 00 53 00 6B 00 13 00 2B 00 43 00 5B 00 73 00 07 00 1F 00 37 00 4F 00 67 00 0F 00 27 00 3F 00 57 00 6F 00 17 00 2F 00 47 00 5F 00 77 00) */; internal static readonly __StaticArrayInitTypeSize=24 CDD66BBE1AE22B32A8D0096C1B85DD3195D15E52BB6401233F6BEE1499B2DD63/* Not supported: data(00 40 00 00 93 5D 00 00 BD 70 00 00 ED 79 00 00 B2 7D 00 00 24 7F 00 00) */; internal static readonly int D026F9BD5D151886B759A7A7BD77EF0526F10893D90521E0E98A855B0EB47B6E/* Not supported: data(E8 9E 0A 00) */; internal static readonly __StaticArrayInitTypeSize=152 D09AA0105B9E386637B4C3BF0239359CE4BD5A93D698EDC6FD1BFB80A9B20ACE/* Not supported: data(81 00 CF 32 00 EC 81 14 00 F5 B9 48 0A 00 F9 D5 81 2A 06 00 FA E2 A9 57 1B 04 00 FB E9 C2 82 3E 14 04 00 FA EC CF A0 63 2F 11 03 00 FF F0 D9 B6 83 51 29 0B 01 00 FF FE E9 C9 9F 6B 3D 14 02 01 00 FF F9 E9 CE AA 80 56 32 17 07 01 00 FF FA EE D9 BA 94 6C 46 27 12 06 01 00 FF FC F3 E2 C8 A6 80 5A 38 1E 0D 04 01 00 FF FC F5 E7 D1 B4 92 6E 4C 2F 19 0B 04 01 00 FF FD F8 ED DB C2 A3 80 5D 3E 25 13 08 03 01 00 FF FE FA F1 E2 CD B1 91 6F 4F 33 1E 0F 06 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=40 D0E0908495BF8436D77F2238D0BCF4BC38A0759F2C71F70BFBAA06F2D547C970/* Not supported: data(E4 57 05 C5 03 00 F2 FF EC FF F1 FF 02 00 19 00 25 00 19 00 F0 FF B9 FF 95 FF B1 FF 32 00 24 01 6F 02 D6 03 08 05 B8 05) */; internal static readonly __StaticArrayInitTypeSize=32 D1030C785E8BEE2ABDD68045C1E512C3370F1A0019F9E4DFFCAD51A469A82D1E/* Not supported: data(F8 2A 00 00 E8 03 00 00 B0 36 00 00 E8 03 00 00 08 52 00 00 D0 07 00 00 60 6D 00 00 D0 07 00 00) */; internal static readonly __StaticArrayInitTypeSize=960 D1F8F188C1C153D7B59F01FF6292637DACAD3272D451907434BAADA374BAA33B/* Not supported: data(00 00 60 00 C0 00 20 01 80 01 20 00 80 00 E0 00 40 01 A0 01 40 00 A0 00 00 01 60 01 C0 01 08 00 68 00 C8 00 28 01 88 01 28 00 88 00 E8 00 48 01 A8 01 48 00 A8 00 08 01 68 01 C8 01 10 00 70 00 D0 00 30 01 90 01 30 00 90 00 F0 00 50 01 B0 01 50 00 B0 00 10 01 70 01 D0 01 18 00 78 00 D8 00 38 01 98 01 38 00 98 00 F8 00 58 01 B8 01 58 00 B8 00 18 01 78 01 D8 01 04 00 64 00 C4 00 24 01 84 01 24 00 84 00 E4 00 44 01 A4 01 44 00 A4 00 04 01 64 01 C4 01 0C 00 6C 00 CC 00 2C 01 8C 01 2C 00 8C 00 EC 00 4C 01 AC 01 4C 00 AC 00 0C 01 6C 01 CC 01 14 00 74 00 D4 00 34 01 94 01 34 00 94 00 F4 00 54 01 B4 01 54 00 B4 00 14 01 74 01 D4 01 1C 00 7C 00 DC 00 3C 01 9C 01 3C 00 9C 00 FC 00 5C 01 BC 01 5C 00 BC 00 1C 01 7C 01 DC 01 01 00 61 00 C1 00 21 01 81 01 21 00 81 00 E1 00 41 01 A1 01 41 00 A1 00 01 01 61 01 C1 01 09 00 69 00 C9 00 29 01 89 01 29 00 89 00 E9 00 49 01 A9 01 49 00 A9 00 09 01 69 01 C9 01 11 00 71 00 D1 00 31 01 91 01 31 00 91 00 F1 00 51 01 B1 01 51 00 B1 00 11 01 71 01 D1 01 19 00 79 00 D9 00 39 01 99 01 39 00 99 00 F9 00 59 01 B9 01 59 00 B9 00 19 01 79 01 D9 01 05 00 65 00 C5 00 25 01 85 01 25 00 85 00 E5 00 45 01 A5 01 45 00 A5 00 05 01 65 01 C5 01 0D 00 6D 00 CD 00 2D 01 8D 01 2D 00 8D 00 ED 00 4D 01 AD 01 4D 00 AD 00 0D 01 6D 01 CD 01 15 00 75 00 D5 00 35 01 95 01 35 00 95 00 F5 00 55 01 B5 01 55 00 B5 00 15 01 75 01 D5 01 1D 00 7D 00 DD 00 3D 01 9D 01 3D 00 9D 00 FD 00 5D 01 BD 01 5D 00 BD 00 1D 01 7D 01 DD 01 02 00 62 00 C2 00 22 01 82 01 22 00 82 00 E2 00 42 01 A2 01 42 00 A2 00 02 01 62 01 C2 01 0A 00 6A 00 CA 00 2A 01 8A 01 2A 00 8A 00 EA 00 4A 01 AA 01 4A 00 AA 00 0A 01 6A 01 CA 01 12 00 72 00 D2 00 32 01 92 01 32 00 92 00 F2 00 52 01 B2 01 52 00 B2 00 12 01 72 01 D2 01 1A 00 7A 00 DA 00 3A 01 9A 01 3A 00 9A 00 FA 00 5A 01 BA 01 5A 00 BA 00 1A 01 7A 01 DA 01 06 00 66 00 C6 00 26 01 86 01 26 00 86 00 E6 00 46 01 A6 01 46 00 A6 00 06 01 66 01 C6 01 0E 00 6E 00 CE 00 2E 01 8E 01 2E 00 8E 00 EE 00 4E 01 AE 01 4E 00 AE 00 0E 01 6E 01 CE 01 16 00 76 00 D6 00 36 01 96 01 36 00 96 00 F6 00 56 01 B6 01 56 00 B6 00 16 01 76 01 D6 01 1E 00 7E 00 DE 00 3E 01 9E 01 3E 00 9E 00 FE 00 5E 01 BE 01 5E 00 BE 00 1E 01 7E 01 DE 01 03 00 63 00 C3 00 23 01 83 01 23 00 83 00 E3 00 43 01 A3 01 43 00 A3 00 03 01 63 01 C3 01 0B 00 6B 00 CB 00 2B 01 8B 01 2B 00 8B 00 EB 00 4B 01 AB 01 4B 00 AB 00 0B 01 6B 01 CB 01 13 00 73 00 D3 00 33 01 93 01 33 00 93 00 F3 00 53 01 B3 01 53 00 B3 00 13 01 73 01 D3 01 1B 00 7B 00 DB 00 3B 01 9B 01 3B 00 9B 00 FB 00 5B 01 BB 01 5B 00 BB 00 1B 01 7B 01 DB 01 07 00 67 00 C7 00 27 01 87 01 27 00 87 00 E7 00 47 01 A7 01 47 00 A7 00 07 01 67 01 C7 01 0F 00 6F 00 CF 00 2F 01 8F 01 2F 00 8F 00 EF 00 4F 01 AF 01 4F 00 AF 00 0F 01 6F 01 CF 01 17 00 77 00 D7 00 37 01 97 01 37 00 97 00 F7 00 57 01 B7 01 57 00 B7 00 17 01 77 01 D7 01 1F 00 7F 00 DF 00 3F 01 9F 01 3F 00 9F 00 FF 00 5F 01 BF 01 5F 00 BF 00 1F 01 7F 01 DF 01) */; internal static readonly __StaticArrayInitTypeSize=12 D338BE1DA9B558AABE5A6D814A8DD892054A6561EB78168780220A0B039988CD/* Not supported: data(00 00 01 FF 01 FF 02 FE 02 FE 03 FD) */; internal static readonly __StaticArrayInitTypeSize=21 D3D6800CE52346EAE1D036FE16236BF31753BB0019E1070270602908D29C43EC/* Not supported: data(D2 D0 CE CB C7 C1 B7 A8 8E 68 4A 34 25 1B 14 0E 0A 06 04 02 00) */; internal static readonly __StaticArrayInitTypeSize=6 D578E94DDDB00A311DDC5A3D7F51BABE21C1995699A1A8285B6C1D1ED491362F/* Not supported: data(D5 AB 80 55 2B 00) */; internal static readonly __StaticArrayInitTypeSize=18 D76FA0CC629785A22C0ABE422BF42820872B575CF67F244155F9C3BE23924F7C/* Not supported: data(FF E0 E0 B6 9B 86 76 6D 68 66 6A 6F 76 83 91 A0 AD 83) */; internal static readonly __StaticArrayInitTypeSize=5 D82D24DC1F53427778D83C8F9FA2BE5F1486FC63B99C150B0CC0C2E1D5470EAF/* Not supported: data(F4 37 4C F4 08) */; internal static readonly __StaticArrayInitTypeSize=16 D849A64133D9C35ACD94A0297A2FBEF3F625D5CEF48E342DE4B8162388C72E2A/* Not supported: data(30 75 00 00 70 17 00 00 20 D1 FF FF 20 D1 FF FF) */; internal static readonly __StaticArrayInitTypeSize=34 D8A2A0E96CA1CA6B66AB8B43DC16D843F8BBD5E4AFC830AA24504B0BDAE794B1/* Not supported: data(64 00 03 00 28 00 03 00 03 00 03 00 05 00 0E 00 0E 00 0A 00 0B 00 03 00 08 00 09 00 07 00 03 00 5B 01) */; internal static readonly __StaticArrayInitTypeSize=5 D8A938A0DE79D325F8CB2D7A52E365F0DE1B42516D04083A779FED766C137780/* Not supported: data(28 09 1A 03 09) */; internal static readonly __StaticArrayInitTypeSize=5 D9B3C872738AB8BDBF592919947EEA2AC80BF59186E0CB52A4AE1EA9E4C7F771/* Not supported: data(F9 14 65 F9 04) */; internal static readonly __StaticArrayInitTypeSize=5 D9B88CF448119D16AA09681F7FC774D2B03D508A3012821E210174E067268741/* Not supported: data(02 00 09 0A 58) */; internal static readonly __StaticArrayInitTypeSize=5 DA6D5EC2F51EF1690604E7301AF4646262BCBD973C41CAB90F200C73351AB1E2/* Not supported: data(FF 24 40 1B FA) */; internal static readonly __StaticArrayInitTypeSize=288 DAA89D127CDBD8EAFD3FADDDE140A35078CFA576F0141AE8BBE06E4B037D1B8C/* Not supported: data(C1 53 4C CE 1E E2 EF 3F 00 00 00 00 00 00 F0 3F C1 53 4C CE 1E E2 EF 3F CF 42 C8 9A 0D 89 EF 3F 0C 6D E7 98 7F F6 EE 3F 88 12 2D 79 3C 2D EE 3F 9A 4D F4 B7 0C 31 ED 3F B5 B0 C0 BA 9E 06 EC 3F CC 99 0E 19 66 B3 EA 3F DC 79 2C C7 75 3D E9 3F 51 AB 22 BB 56 AB E7 3F 95 36 C9 4D DC 03 E6 3F 75 AB E7 A4 F7 4D E4 3F 77 00 9B DE 8B 90 E2 3F 13 81 EA 1F 44 D2 E0 3F C6 00 C3 D1 D9 32 DE 3F 53 3E 04 55 A3 D7 DA 3F D9 08 61 C1 3F 9D D7 3F A8 6A 06 E1 9F 8C D4 3F 6E 24 7D 18 29 AD D1 3F 5A EF 79 F6 43 09 CE 3F 1B 00 60 2B 57 2E C9 3F 51 96 6B 1B 90 CE C4 3F 8B EC 5A AD D9 EB C0 3F E9 D6 29 5E 7E 0A BB 3F DF 17 FA D4 6F 2E B5 3F 06 0D 81 4C 00 38 B0 3F CA BD 44 E5 F4 2F A8 3F A6 15 F8 ED 98 78 A1 3F 4B F5 53 D2 79 43 98 3F 94 CF 9F F4 8D 01 90 3F 00 6E 37 3D FF A8 83 3F DE 69 19 46 CD 99 75 3F E0 85 8C CB E1 28 63 3F FC A9 F1 D2 4D 62 40 3F 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=120 DD0CE5EE475834561EF279FBEF716495103C33CBE34BC5DF1A10E630AF01F26D/* Not supported: data(01 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 07 00 00 00 00 00 00 00 04 00 00 00 03 00 00 00 06 00 00 00 01 00 00 00 05 00 00 00 02 00 00 00 0F 00 00 00 00 00 00 00 08 00 00 00 07 00 00 00 0C 00 00 00 03 00 00 00 0B 00 00 00 04 00 00 00 0E 00 00 00 01 00 00 00 09 00 00 00 06 00 00 00 0D 00 00 00 02 00 00 00 0A 00 00 00 05 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 DDAB2ABDED5D02C13AC68A6E0149F23FCAAB696DBCC5AA1F3CAAD0A243B668FC/* Not supported: data(14 04 51 31 E3) */; internal static readonly long DE107AD6C0B01E4CFB4A7327283E27A55E747DE61E7536441F849F155E46ECE8/* Not supported: data(0F 83 8A 8A 9B 9B AD AD) */; internal static readonly __StaticArrayInitTypeSize=15 DEAB912F6F886CC279EE6C561B67D32D5D5F08925714CF01F1819D02189E6224/* Not supported: data(04 00 02 00 00 00 09 04 07 04 00 03 0C 07 07) */; internal static readonly __StaticArrayInitTypeSize=120 E20BBBE9C0E6AB43E62F3740E2BF8A2908A06138A224814F0BEDD4DB5A2A0AA5/* Not supported: data(00 00 0C 00 18 00 24 00 30 00 04 00 10 00 1C 00 28 00 34 00 08 00 14 00 20 00 2C 00 38 00 01 00 0D 00 19 00 25 00 31 00 05 00 11 00 1D 00 29 00 35 00 09 00 15 00 21 00 2D 00 39 00 02 00 0E 00 1A 00 26 00 32 00 06 00 12 00 1E 00 2A 00 36 00 0A 00 16 00 22 00 2E 00 3A 00 03 00 0F 00 1B 00 27 00 33 00 07 00 13 00 1F 00 2B 00 37 00 0B 00 17 00 23 00 2F 00 3B 00) */; internal static readonly __StaticArrayInitTypeSize=25 E24A86B1466A3D96A623286014BDA53F5C6093CC9E889A6ABA534572860D9566/* Not supported: data(67 64 5C 55 51 4D 48 46 4E 4B 49 47 4E 4A 45 48 46 4A 4C 47 3C 3C 3C 3C 3C) */; internal static readonly __StaticArrayInitTypeSize=18 E30E20E44D72B14100FA0BDF4A3D30DD242CE36A5E5850ED32A0E0B9F4F1927A/* Not supported: data(AD 73 55 49 4C 5C 73 91 AD CD E0 E0 FF FF FF FF FF FF) */; internal static readonly __StaticArrayInitTypeSize=60 E563167A2449A8708E057D0E9410AABCBBEEA4FA49E153B740B8232C06C93BE8/* Not supported: data(00 00 00 00 B0 00 00 00 5F 01 00 00 0D 02 00 00 BA 02 00 00 66 03 00 00 11 04 00 00 6B 04 00 00 9A 04 00 00 B7 04 00 00 CA 04 00 00 D8 04 00 00 E0 04 00 00 E6 04 00 00 E9 04 00 00) */; internal static readonly __StaticArrayInitTypeSize=210 E5F82D7437565608CC2A813F06B343B44A5C6290BBB896CD056A998814234595/* Not supported: data(FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 29 00 29 00 29 00 52 00 52 00 7B 00 A4 00 C8 00 DE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 00 29 00 29 00 29 00 7B 00 7B 00 7B 00 A4 00 A4 00 F0 00 0A 01 1B 01 27 01 29 00 29 00 29 00 29 00 29 00 29 00 29 00 29 00 7B 00 7B 00 7B 00 7B 00 F0 00 F0 00 F0 00 0A 01 0A 01 31 01 3E 01 48 01 50 01 7B 00 7B 00 7B 00 7B 00 7B 00 7B 00 7B 00 7B 00 F0 00 F0 00 F0 00 F0 00 31 01 31 01 31 01 3E 01 3E 01 57 01 5F 01 66 01 6C 01 F0 00 F0 00 F0 00 F0 00 F0 00 F0 00 F0 00 F0 00 31 01 31 01 31 01 31 01 57 01 57 01 57 01 5F 01 5F 01 72 01 78 01 7E 01 83 01) */; internal static readonly __StaticArrayInitTypeSize=24 E6C40A159CA5EA4ACBF5977EBD3033EB7A83AA179064BF5ABDB362FC698953D3/* Not supported: data(ED 00 00 00 99 00 00 00 49 00 00 00 1E 00 00 00 0C 00 00 00 07 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 E8ECA4040F7A605F4C89FBA251A6948D5852E5F7EC0D0ABD1596E04A71FCF6E2/* Not supported: data(03 F8 5F 1C 04) */; internal static readonly __StaticArrayInitTypeSize=16 E94764AB54E9D5C2337081083435A11E38B014AF12A571102F4792C27190CF0F/* Not supported: data(00 0F 08 07 04 0B 0C 03 02 0D 0A 05 06 09 0E 01) */; internal static readonly __StaticArrayInitTypeSize=512 EAF5BD966EF8F794F20B325FEE4428AFECD5AF6607BE0E6A565BFD0AA8CED9F4/* Not supported: data(07 17 26 36 45 55 64 74 83 93 A2 B2 C1 D0 DF EF 0D 19 29 37 45 53 62 70 7F 8E 9D AB BB CB DC EC 0F 15 22 33 3D 4E 5C 6A 7E 88 98 A7 B9 CD E1 F0 0A 15 24 32 3F 4F 5F 6E 7E 8D 9D AD BD CD DD ED 11 14 25 33 3B 4E 59 6B 7B 86 96 A4 B8 CD E0 F0 0A 0F 20 33 43 51 60 70 81 8E 9E AD BD CC DC EC 08 15 25 33 41 4F 62 71 7E 8A 9B A8 B3 C0 D1 DA 0C 0F 22 37 3F 4E 57 6C 76 83 94 A7 B9 CB DB EC 10 13 20 24 38 4F 5B 6C 76 88 9A AB BA CC DC ED 0B 1C 2B 3A 4A 59 69 78 87 96 A5 B4 C4 D3 E2 F1 06 10 21 2E 3C 4B 5C 6B 7B 89 9C A9 B9 C7 D6 E1 0B 13 1E 2C 39 4A 59 69 79 87 98 A9 BA CA DA EA 0C 13 1D 2E 39 47 58 64 78 84 94 A5 B6 C7 D8 E9 11 17 23 2E 38 4D 5C 6A 7B 86 98 A7 B9 CC DE ED 0E 11 2D 35 3F 4B 59 6B 73 84 97 AB BC CE DD F0 09 10 1D 28 38 47 58 67 77 89 9A AB BD CD DE ED 10 13 24 30 39 4C 57 69 76 84 96 A7 B9 CA DA EC 0C 11 1D 36 47 51 5E 68 7E 88 95 A4 B6 C9 DD ED 0F 1C 2F 3E 4F 61 73 81 8E 9B A8 B4 C2 D0 DF EE 08 0E 1E 2D 3E 4E 5E 6F 7F 8F 9F AF C0 CF DF EF 11 1E 31 3E 4F 5C 6B 77 84 91 A0 AE BE CC DC EB 0E 13 24 2D 3D 4C 5B 6C 79 8A 9A AC BD CD DE EE 0C 12 1F 2D 3C 4C 5B 6B 7B 8A 9A AB BB CC DD EC 0D 11 1F 2B 35 46 53 67 72 83 95 A7 B9 CB DC ED 11 16 23 2A 3A 4E 5D 6E 7D 8B 9B AA BC CE E0 F0 08 0F 22 32 43 53 63 73 83 92 A2 B2 C1 D1 E0 EF 0D 10 29 42 49 56 5F 6F 80 89 96 A3 B7 CE E1 F1 11 19 25 34 3F 4B 5C 66 77 84 90 A0 AF BF D4 E7 13 1F 31 41 53 64 75 85 93 A1 AE BB C8 D5 E3 F2 12 1F 34 44 58 67 75 7E 8A 95 A3 B1 C0 CF DF EF 10 1D 2F 3D 4C 5A 6A 77 85 93 A1 B0 C1 D1 E0 F0 0F 15 23 32 3D 49 56 61 6E 77 81 8D AF C6 DA ED) */; internal static readonly __StaticArrayInitTypeSize=11 EAFF4641DF5BD8376C6064CC2284A5956C15369E8EB5BB406B08C1BAAE5CC86D/* Not supported: data(00 FF 02 01 00 01 01 00 00 FF FF) */; internal static readonly __StaticArrayInitTypeSize=32 EBAD9A42863177D34910BF3228B993E4042F319159977803FA185AC2082FA24F/* Not supported: data(05 00 60 00 03 00 20 00 04 00 08 00 02 00 04 00 04 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00) */; internal static readonly __StaticArrayInitTypeSize=5 EBDA78F9B562077949E83047FA741B556B5339A66079797905C8D4D71BD5D0EF/* Not supported: data(F9 0A 37 2B 11) */; internal static readonly __StaticArrayInitTypeSize=5 EDEBF744ED5B4EDBF4A2DF33A79C2F41E57850F540DE2E8783210950315779C1/* Not supported: data(03 F8 2A 1A 00) */; internal static readonly __StaticArrayInitTypeSize=18 EE22961112FC552CFC84D1D9329BC2CC8732A099CCF0EE66C72FD4738C568575/* Not supported: data(F9 EB D5 B9 9C 80 67 53 42 35 2A 21 1A 15 11 0D 0A 00) */; internal static readonly __StaticArrayInitTypeSize=5 EFCE3658B154D19CD10E03E45B4BB5DAE9900F28311394F00F57F524E3D5E731/* Not supported: data(FA 5F 29 F4 05) */; internal static readonly __StaticArrayInitTypeSize=256 F1ACD878A946710771E788F78BD46559A940903490E5AD1BC6FE7F2EC199ADD7/* Not supported: data(00 00 00 00 00 00 00 01 64 66 66 44 44 24 22 60 A4 6B 9E B9 B4 B9 8B 66 40 42 24 22 22 00 01 20 D0 8B 8D BF 98 B9 9B 68 60 AB 68 A6 66 66 66 84 01 00 00 00 00 10 10 00 50 6D 4E 6B B9 8B 67 65 D0 D4 8D 8B AD 99 7B 67 24 00 00 00 00 00 00 01 30 00 00 00 00 00 00 20 44 87 7B 77 77 67 45 62 44 67 78 76 76 66 47 62 86 88 9D B8 B6 99 8B 86 D0 A8 F8 4B BD 8F 79 6B 20 31 22 22 22 00 11 02 D2 EB 8B 7B B9 89 69 86 62 87 68 B6 64 B7 AB 86 64 46 44 46 42 42 22 83 40 A6 66 44 24 02 01 00 86 A6 66 44 22 22 42 84 D4 F6 9E 8B 6B 6B 57 66 64 DB 7D 7A 89 76 67 84 72 87 89 69 AB 6A 32 22 A4 D6 8D 8F B9 97 79 67 C0 22 00 00 00 00 00 01 D0 6D 4A BB 86 F9 9F 89 66 6E 9A 76 57 65 77 65 00 02 00 24 24 42 44 23 60 A4 66 64 24 00 02 21 A7 8A AE 66 64 54 02 02 64 6B 78 77 24 C5 18 00) */; internal static readonly __StaticArrayInitTypeSize=42 F3A66823D7CB4BC6DD763320971CB4F640B827DB206D7FFD64C9058EDC3D6861/* Not supported: data(00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 08 00 08 00 08 00 10 00 10 00 10 00 15 00 15 00 18 00 1D 00 22 00 24 00) */; internal static readonly __StaticArrayInitTypeSize=16 F6371CA85B248A158F212C7B7C5675534F7AA13366056434CD8A46AB2E2773E7/* Not supported: data(00 01 01 01 02 03 03 03 02 03 03 03 02 03 03 03) */; internal static readonly __StaticArrayInitTypeSize=18 F637F3399D987F91BFC93248D9B8C0ADEE74B47F57C4040A6DBDDB66327BFF69/* Not supported: data(FA E5 BC 87 56 33 1E 13 0D 0A 08 06 05 04 03 02 01 00) */; internal static readonly __StaticArrayInitTypeSize=11 F75AB7365DACE3EF02B4CC4149449A859D8C6C3B43FA16BA33EA907DF64C2446/* Not supported: data(00 02 FF FF FF 00 00 01 01 00 01) */; internal static readonly __StaticArrayInitTypeSize=32 F7FFCF175DF7D9EE9EC587D153461BB511E13B6042D9ECE17157CCDC2B8A608E/* Not supported: data(F8 2A 00 00 E8 03 00 00 B0 36 00 00 E8 03 00 00 68 42 00 00 E8 03 00 00 08 52 00 00 D0 07 00 00) */; internal static readonly int F8F7BCB4C3C3A0FE4735CD6317CDF44647CA65E1ADEA8F372676B0C0CC7F6F86/* Not supported: data(08 0A 0C 10) */; internal static readonly __StaticArrayInitTypeSize=5 F90684A455591FFD81B15C6529FE824FE4AC4434F0326F3DB8F136C129E6BBBD/* Not supported: data(12 26 30 17 00) */; internal static readonly __StaticArrayInitTypeSize=34 FA158E0E38F0D5149FB2915F1A32F2A513441F2D01DCCC042A32C78B62B767CD/* Not supported: data(00 01 00 00 00 00 00 00 01 00 01 00 00 01 FF 01 00 00 02 01 FF 02 FF FF 02 FF 02 02 FF 03 FE FE FE 03) */; internal static readonly __StaticArrayInitTypeSize=5 FB0280C26CA5BF348EE9F27DB52EA1493FDE943063D0857F8A462FF85D88DB28/* Not supported: data(F5 2E 68 EA 08) */; internal static readonly __StaticArrayInitTypeSize=18 FB3A2DC64CC74F2C6376EE699AE3749B5686E8115735DE1BE5F48E0258CF94B0/* Not supported: data(E0 B6 86 65 53 4F 55 61 78 91 AD CD E0 FF FF FF FF FF) */; internal static readonly __StaticArrayInitTypeSize=22 FE3EC667EABEA4ECF787BD26972F88113128ADE0CA2928592AE00E9593A93C96/* Not supported: data(FA 00 03 00 06 00 03 00 03 00 03 00 04 00 03 00 03 00 03 00 CD 01) */; internal static readonly __StaticArrayInitTypeSize=6 FF435D61A74BFA376E2F8B01D09465C0FD6D29EE84C0377CB6C3BE18FEEA2523/* Not supported: data(40 27 C8 1B 98 10) */; } namespace Concentus.Oggfile { internal static class BinaryHelpers { internal static void Int16ToByteArrayLittleEndian(short val, byte[] target, int targetOffset) { UInt16ToByteArrayLittleEndian((ushort)val, target, targetOffset); } internal static void UInt16ToByteArrayLittleEndian(ushort val, byte[] target, int targetOffset) { target[targetOffset + 1] = (byte)((val >> 8) & 0xFF); target[targetOffset] = (byte)(val & 0xFF); } internal static void Int16ToByteSpanLittleEndian(short val, ref Span target) { UInt16ToByteArraySpanEndian((ushort)val, ref target); } internal static void UInt16ToByteArraySpanEndian(ushort val, ref Span target) { target[1] = (byte)((val >> 8) & 0xFF); target[0] = (byte)(val & 0xFF); } internal static void Int16ToByteArrayBigEndian(short val, byte[] target, int targetOffset) { UInt16ToByteArrayBigEndian((ushort)val, target, targetOffset); } internal static void UInt16ToByteArrayBigEndian(ushort val, byte[] target, int targetOffset) { target[targetOffset] = (byte)((val >> 8) & 0xFF); target[targetOffset + 1] = (byte)(val & 0xFF); } internal static void Int16ToByteSpanBigEndian(short val, ref Span target) { UInt16ToByteSpanBigEndian((ushort)val, ref target); } internal static void UInt16ToByteSpanBigEndian(ushort val, ref Span target) { target[0] = (byte)((val >> 8) & 0xFF); target[1] = (byte)(val & 0xFF); } internal static void Int32ToByteArrayLittleEndian(int val, byte[] target, int targetOffset) { UInt32ToByteArrayLittleEndian((uint)val, target, targetOffset); } internal static void UInt32ToByteArrayLittleEndian(uint val, byte[] target, int targetOffset) { target[targetOffset + 3] = (byte)((val >> 24) & 0xFF); target[targetOffset + 2] = (byte)((val >> 16) & 0xFF); target[targetOffset + 1] = (byte)((val >> 8) & 0xFF); target[targetOffset] = (byte)(val & 0xFF); } internal static void Int32ToByteSpanLittleEndian(int val, ref Span target) { UInt32ToByteSpanLittleEndian((uint)val, ref target); } internal static void UInt32ToByteSpanLittleEndian(uint val, ref Span target) { target[3] = (byte)((val >> 24) & 0xFF); target[2] = (byte)((val >> 16) & 0xFF); target[1] = (byte)((val >> 8) & 0xFF); target[0] = (byte)(val & 0xFF); } internal static void UInt24ToByteArrayBigEndian(uint val, byte[] target, int targetOffset) { target[targetOffset] = (byte)((val >> 16) & 0xFF); target[targetOffset + 1] = (byte)((val >> 8) & 0xFF); target[targetOffset + 2] = (byte)(val & 0xFF); } internal static void UInt24ToByteSpanBigEndian(uint val, ref Span target) { target[0] = (byte)((val >> 16) & 0xFF); target[1] = (byte)((val >> 8) & 0xFF); target[2] = (byte)(val & 0xFF); } internal static void Int32ToByteArrayBigEndian(int val, byte[] target, int targetOffset) { UInt32ToByteArrayBigEndian((uint)val, target, targetOffset); } internal static void UInt32ToByteArrayBigEndian(uint val, byte[] target, int targetOffset) { target[targetOffset] = (byte)((val >> 24) & 0xFF); target[targetOffset + 1] = (byte)((val >> 16) & 0xFF); target[targetOffset + 2] = (byte)((val >> 8) & 0xFF); target[targetOffset + 3] = (byte)(val & 0xFF); } internal static void Int32ToByteSpanBigEndian(int val, ref Span target) { UInt32ToByteSpanBigEndian((uint)val, ref target); } internal static void UInt32ToByteSpanBigEndian(uint val, ref Span target) { target[0] = (byte)((val >> 24) & 0xFF); target[1] = (byte)((val >> 16) & 0xFF); target[2] = (byte)((val >> 8) & 0xFF); target[3] = (byte)(val & 0xFF); } internal static void Int64ToByteArrayLittleEndian(long val, byte[] target, int targetOffset) { UInt64ToByteArrayLittleEndian((ulong)val, target, targetOffset); } internal static void UInt64ToByteArrayLittleEndian(ulong val, byte[] target, int targetOffset) { target[targetOffset + 7] = (byte)((val >> 56) & 0xFF); target[targetOffset + 6] = (byte)((val >> 48) & 0xFF); target[targetOffset + 5] = (byte)((val >> 40) & 0xFF); target[targetOffset + 4] = (byte)((val >> 32) & 0xFF); target[targetOffset + 3] = (byte)((val >> 24) & 0xFF); target[targetOffset + 2] = (byte)((val >> 16) & 0xFF); target[targetOffset + 1] = (byte)((val >> 8) & 0xFF); target[targetOffset] = (byte)(val & 0xFF); } internal static void Int64ToByteSpanLittleEndian(long val, ref Span target) { UInt64ToByteSpanLittleEndian((ulong)val, ref target); } internal static void UInt64ToByteSpanLittleEndian(ulong val, ref Span target) { target[7] = (byte)((val >> 56) & 0xFF); target[6] = (byte)((val >> 48) & 0xFF); target[5] = (byte)((val >> 40) & 0xFF); target[4] = (byte)((val >> 32) & 0xFF); target[3] = (byte)((val >> 24) & 0xFF); target[2] = (byte)((val >> 16) & 0xFF); target[1] = (byte)((val >> 8) & 0xFF); target[0] = (byte)(val & 0xFF); } internal static void Int64ToByteArrayBigEndian(long val, byte[] target, int targetOffset) { UInt64ToByteArrayBigEndian((ulong)val, target, targetOffset); } internal static void UInt64ToByteArrayBigEndian(ulong val, byte[] target, int targetOffset) { target[targetOffset] = (byte)((val >> 56) & 0xFF); target[targetOffset + 1] = (byte)((val >> 48) & 0xFF); target[targetOffset + 2] = (byte)((val >> 40) & 0xFF); target[targetOffset + 3] = (byte)((val >> 32) & 0xFF); target[targetOffset + 4] = (byte)((val >> 24) & 0xFF); target[targetOffset + 5] = (byte)((val >> 16) & 0xFF); target[targetOffset + 6] = (byte)((val >> 8) & 0xFF); target[targetOffset + 7] = (byte)(val & 0xFF); } internal static void Int64ToByteSpanBigEndian(long val, ref Span target) { UInt64ToByteSpanBigEndian((ulong)val, ref target); } internal static void UInt64ToByteSpanBigEndian(ulong val, ref Span target) { target[0] = (byte)((val >> 56) & 0xFF); target[1] = (byte)((val >> 48) & 0xFF); target[2] = (byte)((val >> 40) & 0xFF); target[3] = (byte)((val >> 32) & 0xFF); target[4] = (byte)((val >> 24) & 0xFF); target[5] = (byte)((val >> 16) & 0xFF); target[6] = (byte)((val >> 8) & 0xFF); target[7] = (byte)(val & 0xFF); } internal static short ByteArrayToInt16LittleEndian(byte[] source, int offset) { return (short)((short)(0 | (short)(source[offset + 1] << 8)) | (short)source[offset]); } internal static short ByteSpanToInt16LittleEndian(ref Span source) { return (short)((short)(0 | (short)(source[1] << 8)) | (short)source[0]); } internal static short ByteSpanToInt16LittleEndian(ref ReadOnlySpan source) { return (short)((short)(0 | (short)(source[1] << 8)) | (short)source[0]); } internal static ushort ByteArrayToUInt16LittleEndian(byte[] source, int offset) { return (ushort)((ushort)(0 | (ushort)(source[offset + 1] << 8)) | source[offset]); } internal static ushort ByteSpanToUInt16LittleEndian(ref Span source) { return (ushort)((ushort)(0 | (ushort)(source[1] << 8)) | source[0]); } internal static ushort ByteSpanToUInt16LittleEndian(ref ReadOnlySpan source) { return (ushort)((ushort)(0 | (ushort)(source[1] << 8)) | source[0]); } internal static short ByteArrayToInt16BigEndian(byte[] source, int offset) { return (short)((short)(0 | (short)(source[offset] << 8)) | (short)source[offset + 1]); } internal static short ByteSpanToInt16BigEndian(ref Span source) { return (short)((short)(0 | (short)(source[0] << 8)) | (short)source[1]); } internal static short ByteSpanToInt16BigEndian(ref ReadOnlySpan source) { return (short)((short)(0 | (short)(source[0] << 8)) | (short)source[1]); } internal static ushort ByteArrayToUInt16BigEndian(byte[] source, int offset) { return (ushort)((ushort)(0 | (ushort)(source[offset] << 8)) | source[offset + 1]); } internal static ushort ByteSpanToUInt16BigEndian(ref Span source) { return (ushort)((ushort)(0 | (ushort)(source[0] << 8)) | source[1]); } internal static ushort ByteSpanToUInt16BigEndian(ref ReadOnlySpan source) { return (ushort)((ushort)(0 | (ushort)(source[0] << 8)) | source[1]); } internal static int ByteArrayToInt32LittleEndian(byte[] source, int offset) { return 0 | (source[offset + 3] << 24) | (source[offset + 2] << 16) | (source[offset + 1] << 8) | source[offset]; } internal static int ByteSpanToInt32LittleEndian(ref Span source) { return 0 | (source[3] << 24) | (source[2] << 16) | (source[1] << 8) | source[0]; } internal static int ByteSpanToInt32LittleEndian(ref ReadOnlySpan source) { return 0 | (source[3] << 24) | (source[2] << 16) | (source[1] << 8) | source[0]; } internal static uint ByteArrayToUInt32LittleEndian(byte[] source, int offset) { return (uint)(0 | (source[offset + 3] << 24) | (source[offset + 2] << 16) | (source[offset + 1] << 8) | source[offset]); } internal static uint ByteSpanToUInt32LittleEndian(ref Span source) { return (uint)(0 | (source[3] << 24) | (source[2] << 16) | (source[1] << 8) | source[0]); } internal static uint ByteSpanToUInt32LittleEndian(ref ReadOnlySpan source) { return (uint)(0 | (source[3] << 24) | (source[2] << 16) | (source[1] << 8) | source[0]); } internal static uint ByteArrayToUInt24BigEndian(byte[] source, int offset) { return (uint)(0 | (source[offset] << 16) | (source[offset + 1] << 8) | source[offset + 2]); } internal static uint ByteSpanToUInt24BigEndian(ref Span source) { return (uint)(0 | (source[0] << 16) | (source[1] << 8) | source[2]); } internal static uint ByteSpanToUInt24BigEndian(ref ReadOnlySpan source) { return (uint)(0 | (source[0] << 16) | (source[1] << 8) | source[2]); } internal static int ByteArrayToInt32BigEndian(byte[] source, int offset) { return 0 | (source[offset] << 24) | (source[offset + 1] << 16) | (source[offset + 2] << 8) | source[offset + 3]; } internal static int ByteSpanToInt32BigEndian(ref Span source) { return 0 | (source[0] << 24) | (source[1] << 16) | (source[2] << 8) | source[3]; } internal static int ByteSpanToInt32BigEndian(ref ReadOnlySpan source) { return 0 | (source[0] << 24) | (source[1] << 16) | (source[2] << 8) | source[3]; } internal static uint ByteArrayToUInt32BigEndian(byte[] source, int offset) { return (uint)(0 | (source[offset] << 24) | (source[offset + 1] << 16) | (source[offset + 2] << 8) | source[offset + 3]); } internal static uint ByteSpanToUInt32BigEndian(ref Span source) { return (uint)(0 | (source[0] << 24) | (source[1] << 16) | (source[2] << 8) | source[3]); } internal static uint ByteSpanToUInt32BigEndian(ref ReadOnlySpan source) { return (uint)(0 | (source[0] << 24) | (source[1] << 16) | (source[2] << 8) | source[3]); } internal static long ByteArrayToInt64LittleEndian(byte[] source, int offset) { return (long)(0 | ((ulong)source[offset + 7] << 56) | ((ulong)source[offset + 6] << 48) | ((ulong)source[offset + 5] << 40) | ((ulong)source[offset + 4] << 32) | ((ulong)source[offset + 3] << 24) | ((ulong)source[offset + 2] << 16) | ((ulong)source[offset + 1] << 8) | source[offset]); } internal static long ByteSpanToInt64LittleEndian(ref Span source) { return (long)(0 | ((ulong)source[7] << 56) | ((ulong)source[6] << 48) | ((ulong)source[5] << 40) | ((ulong)source[4] << 32) | ((ulong)source[3] << 24) | ((ulong)source[2] << 16) | ((ulong)source[1] << 8) | source[0]); } internal static long ByteSpanToInt64LittleEndian(ref ReadOnlySpan source) { return (long)(0 | ((ulong)source[7] << 56) | ((ulong)source[6] << 48) | ((ulong)source[5] << 40) | ((ulong)source[4] << 32) | ((ulong)source[3] << 24) | ((ulong)source[2] << 16) | ((ulong)source[1] << 8) | source[0]); } internal static ulong ByteArrayToUInt64LittleEndian(byte[] source, int offset) { return 0 | ((ulong)source[offset + 7] << 56) | ((ulong)source[offset + 6] << 48) | ((ulong)source[offset + 5] << 40) | ((ulong)source[offset + 4] << 32) | ((ulong)source[offset + 3] << 24) | ((ulong)source[offset + 2] << 16) | ((ulong)source[offset + 1] << 8) | source[offset]; } internal static ulong ByteSpanToUInt64LittleEndian(ref Span source) { return 0 | ((ulong)source[7] << 56) | ((ulong)source[6] << 48) | ((ulong)source[5] << 40) | ((ulong)source[4] << 32) | ((ulong)source[3] << 24) | ((ulong)source[2] << 16) | ((ulong)source[1] << 8) | source[0]; } internal static ulong ByteSpanToUInt64LittleEndian(ref ReadOnlySpan source) { return 0 | ((ulong)source[7] << 56) | ((ulong)source[6] << 48) | ((ulong)source[5] << 40) | ((ulong)source[4] << 32) | ((ulong)source[3] << 24) | ((ulong)source[2] << 16) | ((ulong)source[1] << 8) | source[0]; } internal static long ByteArrayToInt64BigEndian(byte[] source, int offset) { return (long)(0 | ((ulong)source[offset] << 56) | ((ulong)source[offset + 1] << 48) | ((ulong)source[offset + 2] << 40) | ((ulong)source[offset + 3] << 32) | ((ulong)source[offset + 4] << 24) | ((ulong)source[offset + 5] << 16) | ((ulong)source[offset + 6] << 8) | source[offset + 7]); } internal static long ByteSpanToInt64BigEndian(ref Span source) { return (long)(0 | ((ulong)source[0] << 56) | ((ulong)source[1] << 48) | ((ulong)source[2] << 40) | ((ulong)source[3] << 32) | ((ulong)source[4] << 24) | ((ulong)source[5] << 16) | ((ulong)source[6] << 8) | source[7]); } internal static long ByteSpanToInt64BigEndian(ref ReadOnlySpan source) { return (long)(0 | ((ulong)source[0] << 56) | ((ulong)source[1] << 48) | ((ulong)source[2] << 40) | ((ulong)source[3] << 32) | ((ulong)source[4] << 24) | ((ulong)source[5] << 16) | ((ulong)source[6] << 8) | source[7]); } internal static ulong ByteArrayToUInt64BigEndian(byte[] source, int offset) { return 0 | ((ulong)source[offset] << 56) | ((ulong)source[offset + 1] << 48) | ((ulong)source[offset + 2] << 40) | ((ulong)source[offset + 3] << 32) | ((ulong)source[offset + 4] << 24) | ((ulong)source[offset + 5] << 16) | ((ulong)source[offset + 6] << 8) | source[offset + 7]; } internal static ulong ByteSpanToUInt64BigEndian(ref Span source) { return 0 | ((ulong)source[0] << 56) | ((ulong)source[1] << 48) | ((ulong)source[2] << 40) | ((ulong)source[3] << 32) | ((ulong)source[4] << 24) | ((ulong)source[5] << 16) | ((ulong)source[6] << 8) | source[7]; } internal static ulong ByteSpanToUInt64BigEndian(ref ReadOnlySpan source) { return 0 | ((ulong)source[0] << 56) | ((ulong)source[1] << 48) | ((ulong)source[2] << 40) | ((ulong)source[3] << 32) | ((ulong)source[4] << 24) | ((ulong)source[5] << 16) | ((ulong)source[6] << 8) | source[7]; } } internal class BufferedReadStream : Stream { private const int DEFAULT_INITIAL_SIZE = 32768; private const int DEFAULT_MAX_SIZE = 262144; private Stream _baseStream; private StreamReadBuffer _buffer; private long _readPosition; public bool CloseBaseStream { get; set; } public bool MinimalRead { get { return _buffer.MinimalRead; } set { _buffer.MinimalRead = value; } } public int MaxBufferSize { get { return _buffer.MaxSize; } set { CheckLock(); _buffer.MaxSize = value; } } public long BufferBaseOffset => _buffer.BaseOffset; public int BufferBytesFilled => _buffer.BytesFilled; public override bool CanRead => true; public override bool CanSeek => true; public override bool CanWrite => false; public override long Length => _baseStream.Length; public override long Position { get { return _readPosition; } set { Seek(value, SeekOrigin.Begin); } } public BufferedReadStream(Stream baseStream) : this(baseStream, 32768, 262144, minimalRead: false) { } public BufferedReadStream(Stream baseStream, bool minimalRead) : this(baseStream, 32768, 262144, minimalRead) { } public BufferedReadStream(Stream baseStream, int initialSize, int maxSize) : this(baseStream, initialSize, maxSize, minimalRead: false) { } public BufferedReadStream(Stream baseStream, int initialSize, int maxBufferSize, bool minimalRead) { if (baseStream == null) { throw new ArgumentNullException("baseStream"); } if (!baseStream.CanRead) { throw new ArgumentException("baseStream"); } if (maxBufferSize < 1) { maxBufferSize = 1; } if (initialSize < 1) { initialSize = 1; } if (initialSize > maxBufferSize) { initialSize = maxBufferSize; } _baseStream = baseStream; _buffer = new StreamReadBuffer(baseStream, initialSize, maxBufferSize, minimalRead); _buffer.MaxSize = maxBufferSize; _buffer.MinimalRead = minimalRead; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (_buffer != null) { _buffer.Dispose(); _buffer = null; } _ = CloseBaseStream; } } public void TakeLock() { } private void CheckLock() { } public void ReleaseLock() { } public void Discard(int bytes) { CheckLock(); _buffer.DiscardThrough(_buffer.BaseOffset + bytes); } public void DiscardThrough(long offset) { CheckLock(); _buffer.DiscardThrough(offset); } public override void Flush() { } public override int ReadByte() { CheckLock(); int num = _buffer.ReadByte(Position); if (num > -1) { Seek(1L, SeekOrigin.Current); } return num; } public override int Read(byte[] buffer, int offset, int count) { CheckLock(); int num = _buffer.Read(Position, buffer, offset, count); Seek(num, SeekOrigin.Current); return num; } public override long Seek(long offset, SeekOrigin origin) { CheckLock(); switch (origin) { case SeekOrigin.Current: offset += Position; break; case SeekOrigin.End: offset += _baseStream.Length; break; } if (!_baseStream.CanSeek) { if (offset < _buffer.BaseOffset) { throw new InvalidOperationException("Cannot seek to before the start of the buffer!"); } if (offset > _buffer.BufferEndOffset) { throw new InvalidOperationException("Cannot seek to beyond the end of the buffer! Discard some bytes."); } } return _readPosition = offset; } public override void SetLength(long value) { throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } } internal abstract class DataPacket { [Flags] protected enum PacketFlags : byte { IsResync = 1, IsEndOfStream = 2, IsShort = 4, HasGranuleCount = 8, User1 = 0x10, User2 = 0x20, User3 = 0x40, User4 = 0x80 } private ulong _bitBucket; private int _bitCount; private int _readBits; private byte _overflowBits; private PacketFlags _packetFlags; private long _granulePosition; private long _pageGranulePosition; private int _length; private int _granuleCount; private int _pageSequenceNumber; public bool IsResync { get { return GetFlag(PacketFlags.IsResync); } internal set { SetFlag(PacketFlags.IsResync, value); } } public long GranulePosition { get { return _granulePosition; } set { _granulePosition = value; } } public long PageGranulePosition { get { return _pageGranulePosition; } internal set { _pageGranulePosition = value; } } public int Length { get { return _length; } protected set { _length = value; } } public bool IsEndOfStream { get { return GetFlag(PacketFlags.IsEndOfStream); } internal set { SetFlag(PacketFlags.IsEndOfStream, value); } } public long BitsRead => _readBits; public int? GranuleCount { get { if (GetFlag(PacketFlags.HasGranuleCount)) { return _granuleCount; } return null; } set { if (value.HasValue) { _granuleCount = value.Value; SetFlag(PacketFlags.HasGranuleCount, value: true); } else { SetFlag(PacketFlags.HasGranuleCount, value: false); } } } internal int PageSequenceNumber { get { return _pageSequenceNumber; } set { _pageSequenceNumber = value; } } internal bool IsShort { get { return GetFlag(PacketFlags.IsShort); } private set { SetFlag(PacketFlags.IsShort, value); } } protected bool GetFlag(PacketFlags flag) { return (_packetFlags & flag) == flag; } protected void SetFlag(PacketFlags flag, bool value) { if (value) { _packetFlags |= flag; } else { _packetFlags &= (PacketFlags)(byte)(~(int)flag); } } protected DataPacket(int length) { Length = length; } protected abstract int ReadNextByte(); public virtual void Done() { } public ulong TryPeekBits(int count, out int bitsRead) { ulong num = 0uL; 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 num2 = ReadNextByte(); if (num2 == -1) { bitsRead = _bitCount; num = _bitBucket; _bitBucket = 0uL; _bitCount = 0; IsShort = true; return num; } _bitBucket = (ulong)((long)(num2 & 0xFF) << _bitCount) | _bitBucket; _bitCount += 8; if (_bitCount > 64) { _overflowBits = (byte)(num2 >> 72 - _bitCount); } } num = _bitBucket; if (count < 64) { num &= (ulong)((1L << count) - 1); } bitsRead = count; return num; } 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; } } protected void ResetBitReader() { _bitBucket = 0uL; _bitCount = 0; _readBits = 0; IsShort = false; } public ulong ReadBits(int count) { if (count == 0) { return 0uL; } int bitsRead; ulong result = TryPeekBits(count, out bitsRead); SkipBits(count); return result; } public byte PeekByte() { int bitsRead; return (byte)TryPeekBits(8, out bitsRead); } public byte ReadByte() { return (byte)ReadBits(8); } public byte[] ReadBytes(int count) { List list = new List(count); while (list.Count < count) { list.Add(ReadByte()); } return list.ToArray(); } public int Read(byte[] buffer, int index, int count) { if (index < 0 || index + count > buffer.Length) { throw new ArgumentOutOfRangeException("index"); } for (int i = 0; i < count; i++) { int bitsRead; byte b = (byte)TryPeekBits(8, out bitsRead); if (bitsRead == 0) { return i; } buffer[index++] = b; SkipBits(8); } return count; } public bool ReadBit() { return ReadBits(1) == 1; } public short ReadInt16() { return (short)ReadBits(16); } public int ReadInt32() { return (int)ReadBits(32); } public long ReadInt64() { return (long)ReadBits(64); } public ushort ReadUInt16() { return (ushort)ReadBits(16); } public uint ReadUInt32() { return (uint)ReadBits(32); } public ulong ReadUInt64() { return ReadBits(64); } public void SkipBytes(int count) { SkipBits(count * 8); } } internal interface IContainerReader : IDisposable { int[] StreamSerials { get; } bool CanSeek { get; } long WasteBits { get; } int PagesRead { get; } event EventHandler NewStream; bool Init(); bool FindNextStream(); int GetTotalPageCount(); } internal interface IPacketProvider : IDisposable { int StreamSerial { get; } bool CanSeek { get; } long ContainerBits { get; } event EventHandler ParameterChange; int GetTotalPageCount(); DataPacket GetNextPacket(); DataPacket PeekNextPacket(); DataPacket GetPacket(int packetIndex); long GetGranuleCount(); DataPacket FindPacket(long granulePos, Func packetGranuleCountCallback); void SeekToPacket(DataPacket packet, int preRoll); } internal class NewStreamEventArgs : EventArgs { public IPacketProvider PacketProvider { get; private set; } public bool IgnoreStream { get; set; } public NewStreamEventArgs(IPacketProvider packetProvider) { if (packetProvider == null) { throw new ArgumentNullException("packetProvider"); } PacketProvider = packetProvider; } } internal class OggContainerReader : IContainerReader, IDisposable { private class PageHeader { public int StreamSerial { get; set; } public PageFlags Flags { get; set; } public long GranulePosition { get; set; } public int SequenceNumber { get; set; } public long DataOffset { get; set; } public int[] PacketSizes { get; set; } public bool LastPacketContinues { get; set; } public bool IsResync { get; set; } } private Crc _crc = new Crc(); private BufferedReadStream _stream; private Dictionary _packetReaders; private List _disposedStreamSerials; private long _nextPageOffset; private int _pageCount; private byte[] _readBuffer = new byte[65025]; private long _containerBits; private long _wasteBits; public int[] StreamSerials => _packetReaders.Keys.ToArray(); public int PagesRead => _pageCount; public bool CanSeek => _stream.CanSeek; public long WasteBits => _wasteBits; public event EventHandler NewStream; public OggContainerReader(Stream stream, bool closeOnDispose) { _packetReaders = new Dictionary(); _disposedStreamSerials = new List(); _stream = (stream as BufferedReadStream) ?? new BufferedReadStream(stream) { CloseBaseStream = closeOnDispose }; } public bool Init() { _stream.TakeLock(); try { return GatherNextPage() != -1; } finally { _stream.ReleaseLock(); } } public void Dispose() { int[] streamSerials = StreamSerials; foreach (int key in streamSerials) { _packetReaders[key].Dispose(); } _nextPageOffset = 0L; _containerBits = 0L; _wasteBits = 0L; _stream.Dispose(); } public IPacketProvider GetStream(int streamSerial) { if (!_packetReaders.TryGetValue(streamSerial, out var value)) { throw new ArgumentOutOfRangeException("streamSerial"); } return value; } public bool FindNextStream() { if (!CanSeek) { throw new InvalidOperationException(); } int count = _packetReaders.Count; while (_packetReaders.Count == count) { _stream.TakeLock(); try { if (GatherNextPage() == -1) { break; } } finally { _stream.ReleaseLock(); } } return count > _packetReaders.Count; } public int GetTotalPageCount() { if (!CanSeek) { throw new InvalidOperationException(); } while (true) { _stream.TakeLock(); try { if (GatherNextPage() == -1) { break; } } finally { _stream.ReleaseLock(); } } return _pageCount; } private PageHeader ReadPageHeader(long position) { _stream.Seek(position, SeekOrigin.Begin); if (_stream.Read(_readBuffer, 0, 27) != 27) { return null; } if (_readBuffer[0] != 79 || _readBuffer[1] != 103 || _readBuffer[2] != 103 || _readBuffer[3] != 83) { return null; } if (_readBuffer[4] != 0) { return null; } PageHeader pageHeader = new PageHeader(); pageHeader.Flags = (PageFlags)_readBuffer[5]; pageHeader.GranulePosition = BitConverter.ToInt64(_readBuffer, 6); pageHeader.StreamSerial = BitConverter.ToInt32(_readBuffer, 14); pageHeader.SequenceNumber = BitConverter.ToInt32(_readBuffer, 18); uint checkCrc = BitConverter.ToUInt32(_readBuffer, 22); _crc.Reset(); for (int i = 0; i < 22; i++) { _crc.Update(_readBuffer[i]); } _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(0); _crc.Update(_readBuffer[26]); int num = _readBuffer[26]; if (_stream.Read(_readBuffer, 0, num) != num) { return null; } List list = new List(num); int num2 = 0; int num3 = 0; for (int j = 0; j < num; j++) { byte b = _readBuffer[j]; _crc.Update(b); if (num3 == list.Count) { list.Add(0); } list[num3] += b; if (b < byte.MaxValue) { num3++; pageHeader.LastPacketContinues = false; } else { pageHeader.LastPacketContinues = true; } num2 += b; } pageHeader.PacketSizes = list.ToArray(); pageHeader.DataOffset = position + 27 + num; if (_stream.Read(_readBuffer, 0, num2) != num2) { return null; } for (int k = 0; k < num2; k++) { _crc.Update(_readBuffer[k]); } if (_crc.Test(checkCrc)) { _containerBits += 8 * (27 + num); _pageCount++; return pageHeader; } return null; } private PageHeader FindNextPageHeader() { long num = _nextPageOffset; bool isResync = false; PageHeader pageHeader; while ((pageHeader = ReadPageHeader(num)) == null) { isResync = true; _wasteBits += 8L; num = (_stream.Position = num + 1); int num3 = 0; do { switch (_stream.ReadByte()) { case 79: if (_stream.ReadByte() == 103 && _stream.ReadByte() == 103 && _stream.ReadByte() == 83) { num += num3; goto end_IL_0032; } _stream.Seek(-3L, SeekOrigin.Current); break; case -1: return null; } _wasteBits += 8L; continue; end_IL_0032: break; } while (++num3 < 65536); if (num3 == 65536) { return null; } } pageHeader.IsResync = isResync; _nextPageOffset = pageHeader.DataOffset; for (int i = 0; i < pageHeader.PacketSizes.Length; i++) { _nextPageOffset += pageHeader.PacketSizes[i]; } return pageHeader; } private bool AddPage(PageHeader hdr) { if (!_packetReaders.TryGetValue(hdr.StreamSerial, out var value)) { value = new PacketReader(this, hdr.StreamSerial); } value.ContainerBits += _containerBits; _containerBits = 0L; bool isContinued = hdr.PacketSizes.Length == 1 && hdr.LastPacketContinues; bool isContinuation = (hdr.Flags & PageFlags.ContinuesPacket) == PageFlags.ContinuesPacket; bool isEndOfStream = false; bool isResync = hdr.IsResync; long num = hdr.DataOffset; int num2 = hdr.PacketSizes.Length; int[] packetSizes = hdr.PacketSizes; foreach (int num3 in packetSizes) { Packet packet = new Packet(this, num, num3) { PageGranulePosition = hdr.GranulePosition, IsEndOfStream = isEndOfStream, PageSequenceNumber = hdr.SequenceNumber, IsContinued = isContinued, IsContinuation = isContinuation, IsResync = isResync }; value.AddPacket(packet); num += num3; isContinuation = false; isResync = false; if (--num2 == 1) { isContinued = hdr.LastPacketContinues; isEndOfStream = (hdr.Flags & PageFlags.EndOfStream) == PageFlags.EndOfStream; } } if (!_packetReaders.ContainsKey(hdr.StreamSerial)) { _packetReaders.Add(hdr.StreamSerial, value); return true; } return false; } private int GatherNextPage() { PageHeader pageHeader; while (true) { pageHeader = FindNextPageHeader(); if (pageHeader == null) { return -1; } if (!_disposedStreamSerials.Contains(pageHeader.StreamSerial)) { if (!AddPage(pageHeader)) { break; } EventHandler eventHandler = this.NewStream; if (eventHandler == null) { break; } NewStreamEventArgs e = new NewStreamEventArgs(_packetReaders[pageHeader.StreamSerial]); eventHandler(this, e); if (!e.IgnoreStream) { break; } _packetReaders[pageHeader.StreamSerial].Dispose(); } } return pageHeader.StreamSerial; } internal void DisposePacketReader(PacketReader packetReader) { _disposedStreamSerials.Add(packetReader.StreamSerial); _packetReaders.Remove(packetReader.StreamSerial); } internal int PacketReadByte(long offset) { _stream.TakeLock(); try { _stream.Position = offset; return _stream.ReadByte(); } finally { _stream.ReleaseLock(); } } internal void PacketDiscardThrough(long offset) { _stream.TakeLock(); try { _stream.DiscardThrough(offset); } finally { _stream.ReleaseLock(); } } internal void GatherNextPage(int streamSerial) { if (!_packetReaders.ContainsKey(streamSerial)) { throw new ArgumentOutOfRangeException("streamSerial"); } int num; do { _stream.TakeLock(); try { if (_packetReaders[streamSerial].HasEndOfStream) { break; } num = GatherNextPage(); if (num != -1) { continue; } foreach (KeyValuePair packetReader in _packetReaders) { if (!packetReader.Value.HasEndOfStream) { packetReader.Value.SetEndOfStream(); } } break; } finally { _stream.ReleaseLock(); } } while (num != streamSerial); } } internal class Crc { private const uint CRC32_POLY = 79764919u; private static uint[] crcTable; private uint _crc; public uint Value => _crc; static Crc() { 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) ^ (uint)((num2 >= 2147483648u) ? 79764919 : 0); } crcTable[num] = num2; } } public Crc() { Reset(); } public void Reset() { _crc = 0u; } public void Update(int nextVal) { _crc = (_crc << 8) ^ crcTable[nextVal ^ (_crc >> 24)]; } public bool Test(uint checkCrc) { return _crc == checkCrc; } } internal class Packet : DataPacket { private long _offset; private int _length; private int _curOfs; private Packet _mergedPacket; private Packet _next; private Packet _prev; private OggContainerReader _containerReader; internal Packet Next { get { return _next; } set { _next = value; } } internal Packet Prev { get { return _prev; } set { _prev = value; } } internal bool IsContinued { get { return GetFlag(PacketFlags.User1); } set { SetFlag(PacketFlags.User1, value); } } internal bool IsContinuation { get { return GetFlag(PacketFlags.User2); } set { SetFlag(PacketFlags.User2, value); } } internal Packet(OggContainerReader containerReader, long streamOffset, int length) : base(length) { _containerReader = containerReader; _offset = streamOffset; _length = length; _curOfs = 0; } internal void MergeWith(DataPacket continuation) { if (!(continuation is Packet mergedPacket)) { throw new ArgumentException("Incorrect packet type!"); } base.Length += continuation.Length; if (_mergedPacket == null) { _mergedPacket = mergedPacket; } else { _mergedPacket.MergeWith(continuation); } base.PageGranulePosition = continuation.PageGranulePosition; base.PageSequenceNumber = continuation.PageSequenceNumber; } internal void Reset() { _curOfs = 0; ResetBitReader(); if (_mergedPacket != null) { _mergedPacket.Reset(); } } protected override int ReadNextByte() { if (_curOfs == _length) { if (_mergedPacket == null) { return -1; } return _mergedPacket.ReadNextByte(); } int num = _containerReader.PacketReadByte(_offset + _curOfs); if (num != -1) { _curOfs++; } return num; } public override void Done() { if (_mergedPacket != null) { _mergedPacket.Done(); } else { _containerReader.PacketDiscardThrough(_offset + _length); } } } [DebuggerTypeProxy(typeof(DebugView))] internal class PacketReader : IPacketProvider, IDisposable { internal class DebugView { private PacketReader _reader; private Packet _last; private Packet _first; private Packet[] _packetList = new Packet[0]; public OggContainerReader Container => _reader._container; public int StreamSerial => _reader._streamSerial; public bool EndOfStreamFound => _reader._eosFound; public int CurrentPacketIndex { get { if (_reader._current == null) { return -1; } return Array.IndexOf(Packets, _reader._current); } } public Packet[] Packets { get { if (_reader._last == _last && _reader._first == _first) { return _packetList; } _last = _reader._last; _first = _reader._first; List list = new List(); for (Packet packet = _first; packet != null; packet = packet.Next) { list.Add(packet); } _packetList = list.ToArray(); return _packetList; } } public DebugView(PacketReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } _reader = reader; } } private OggContainerReader _container; private int _streamSerial; private bool _eosFound; private Packet _first; private Packet _current; private Packet _last; private object _packetLock = new object(); internal bool HasEndOfStream => _eosFound; public int StreamSerial => _streamSerial; public long ContainerBits { get; set; } public bool CanSeek => _container.CanSeek; public event EventHandler ParameterChange; internal PacketReader(OggContainerReader container, int streamSerial) { _container = container; _streamSerial = streamSerial; } public void Dispose() { _eosFound = true; _container.DisposePacketReader(this); _container = null; _current = null; if (_first != null) { Packet packet = _first; _first = null; while (packet.Next != null) { Packet next = packet.Next; packet.Next = null; packet = next; packet.Prev = null; } packet = null; } _last = null; } internal void AddPacket(Packet packet) { lock (_packetLock) { if (_eosFound) { return; } if (packet.IsResync) { packet.IsContinuation = false; if (_last != null) { _last.IsContinued = false; } } if (packet.IsContinuation) { if (_last == null) { throw new InvalidDataException(); } if (!_last.IsContinued) { throw new InvalidDataException(); } _last.MergeWith(packet); _last.IsContinued = packet.IsContinued; } else { if (packet == null) { throw new ArgumentException("Wrong packet datatype", "packet"); } if (_first == null) { _first = packet; _last = packet; } else { Packet packet2 = (packet.Prev = _last); Packet last2 = (packet2.Next = packet); _last = last2; } } if (packet.IsEndOfStream) { SetEndOfStream(); } } } internal void SetEndOfStream() { lock (_packetLock) { _eosFound = true; if (_last.IsContinued) { _last = _last.Prev; _last.Next.Prev = null; _last.Next = null; } } } public DataPacket GetNextPacket() { return _current = PeekNextPacketInternal(); } public DataPacket PeekNextPacket() { return PeekNextPacketInternal(); } private Packet PeekNextPacketInternal() { Packet packet; if (_current == null) { packet = _first; } else { while (true) { lock (_packetLock) { packet = _current.Next; if ((packet != null && !packet.IsContinued) || _eosFound) { break; } goto IL_004f; } IL_004f: _container.GatherNextPage(_streamSerial); } } if (packet != null) { if (packet.IsContinued) { throw new InvalidDataException("Packet is incomplete!"); } packet.Reset(); } return packet; } internal void ReadAllPages() { if (!CanSeek) { throw new InvalidOperationException(); } while (!_eosFound) { _container.GatherNextPage(_streamSerial); } } internal DataPacket GetLastPacket() { ReadAllPages(); return _last; } public int GetTotalPageCount() { ReadAllPages(); int num = 0; int num2 = 0; for (Packet packet = _first; packet != null; packet = packet.Next) { if (packet.PageSequenceNumber != num2) { num++; num2 = packet.PageSequenceNumber; } } return num; } public DataPacket GetPacket(int packetIndex) { if (!CanSeek) { throw new InvalidOperationException(); } if (packetIndex < 0) { throw new ArgumentOutOfRangeException("index"); } if (_first == null) { throw new InvalidOperationException("Packet reader has no packets!"); } Packet packet = _first; while (--packetIndex >= 0) { while (packet.Next == null) { if (_eosFound) { throw new ArgumentOutOfRangeException("index"); } _container.GatherNextPage(_streamSerial); } packet = packet.Next; } packet.Reset(); return packet; } private Packet GetLastPacketInPage(Packet packet) { if (packet != null) { int pageSequenceNumber = packet.PageSequenceNumber; while (packet.Next != null && packet.Next.PageSequenceNumber == pageSequenceNumber) { packet = packet.Next; } if (packet != null && packet.IsContinued) { packet = packet.Prev; } } return packet; } private Packet FindPacketInPage(Packet pagePacket, long targetGranulePos, Func packetGranuleCountCallback) { Packet lastPacketInPage = GetLastPacketInPage(pagePacket); if (lastPacketInPage == null) { return null; } Packet packet = lastPacketInPage; do { if (!packet.GranuleCount.HasValue) { if (packet == lastPacketInPage) { packet.GranulePosition = packet.PageGranulePosition; } else { packet.GranulePosition = packet.Next.GranulePosition - packet.Next.GranuleCount.Value; } if (packet == _last && _eosFound && packet.Prev.PageSequenceNumber < packet.PageSequenceNumber) { packet.GranuleCount = (int)(packet.GranulePosition - packet.Prev.PageGranulePosition); } else if (packet.Prev != null) { packet.Prev.Reset(); packet.Reset(); packet.GranuleCount = packetGranuleCountCallback(packet, packet.Prev); } else { if (packet.GranulePosition > packet.Next.GranulePosition - packet.Next.GranuleCount) { throw new InvalidOperationException("First data packet size mismatch"); } packet.GranuleCount = (int)packet.GranulePosition; } } if (targetGranulePos <= packet.GranulePosition && targetGranulePos > packet.GranulePosition - packet.GranuleCount) { if (packet.Prev != null && !packet.Prev.GranuleCount.HasValue) { packet.Prev.GranulePosition = packet.GranulePosition - packet.GranuleCount.Value; } return packet; } packet = packet.Prev; } while (packet != null && packet.PageSequenceNumber == lastPacketInPage.PageSequenceNumber); if (packet != null && packet.PageGranulePosition < targetGranulePos) { packet.GranulePosition = packet.PageGranulePosition; return packet.Next; } return null; } public DataPacket FindPacket(long granulePos, Func packetGranuleCountCallback) { if (granulePos < 0) { throw new ArgumentOutOfRangeException("granulePos"); } Packet packet = null; Packet packet2 = _current ?? _first; if (granulePos > packet2.PageGranulePosition) { while (granulePos > packet2.PageGranulePosition) { if ((packet2.Next == null || packet2.IsContinued) && !_eosFound) { _container.GatherNextPage(_streamSerial); if (_eosFound) { packet2 = null; break; } } packet2 = packet2.Next; } return FindPacketInPage(packet2, granulePos, packetGranuleCountCallback); } while (packet2.Prev != null && (granulePos <= packet2.Prev.PageGranulePosition || packet2.Prev.PageGranulePosition == -1)) { packet2 = packet2.Prev; } return FindPacketInPage(packet2, granulePos, packetGranuleCountCallback); } public void SeekToPacket(DataPacket packet, int preRoll) { if (preRoll < 0) { throw new ArgumentOutOfRangeException("preRoll"); } if (packet == null) { throw new ArgumentNullException("granulePos"); } Packet packet2 = packet as Packet; if (packet2 == null) { throw new ArgumentException("Incorrect packet type!", "packet"); } while (--preRoll >= 0) { packet2 = packet2.Prev; if (packet2 == null) { throw new ArgumentOutOfRangeException("preRoll"); } } _current = packet2.Prev; } public long GetGranuleCount() { return GetLastPacket().PageGranulePosition; } } [Flags] internal enum PageFlags { None = 0, ContinuesPacket = 1, BeginningOfStream = 2, EndOfStream = 4 } internal class OpusHeader { private byte version; private byte channel_count; private ushort pre_skip; private uint input_sample_rate; private short output_gain; private byte mapping_family; private byte stream_count; private byte coupled_count; } internal class OpusOggReadStream { private const double GranuleSampleRate = 48000.0; private readonly Stream _stream; private readonly IOpusDecoder _decoder; private byte[] _nextDataPacket; private IPacketProvider _packetProvider; private bool _endOfStream; private OggContainerReader _containerReader; public bool CanSeek => _stream.CanSeek; public OpusTags Tags { get; private set; } public bool HasNextPacket => !_endOfStream; public string LastError { get; private set; } public long PageGranulePosition { get; private set; } public TimeSpan CurrentTime => TimeSpan.FromSeconds((double)PageGranulePosition / 48000.0); public long GranuleCount { get; private set; } public TimeSpan TotalTime => TimeSpan.FromSeconds((double)GranuleCount / 48000.0); public long PagePosition { get; private set; } public long PageCount { get; private set; } public OpusOggReadStream(IOpusDecoder decoder, Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } _stream = stream; _decoder = decoder; _endOfStream = !Initialize(); } public short[] DecodeNextPacket() { if (_decoder == null) { throw new InvalidOperationException("Cannot decode opus packets as a decoder was never provided"); } if (_nextDataPacket == null || _nextDataPacket.Length == 0) { _endOfStream = true; return null; } try { int numSamples = OpusPacketInfo.GetNumSamples(MemoryExtensions.AsSpan(_nextDataPacket), _decoder.SampleRate); short[] array = new short[numSamples * _decoder.NumChannels]; _decoder.Decode(MemoryExtensions.AsSpan(_nextDataPacket), MemoryExtensions.AsSpan(array), numSamples); QueueNextPacket(); return array; } catch (OpusException ex) { LastError = "Opus decoder threw exception: " + ex.Message; return null; } } public byte[] ReadNextRawPacket() { if (_nextDataPacket == null || _nextDataPacket.Length == 0) { _endOfStream = true; return null; } byte[] nextDataPacket = _nextDataPacket; QueueNextPacket(); return nextDataPacket; } private bool Initialize() { try { OggContainerReader oggContainerReader = new OggContainerReader(_stream, closeOnDispose: true); if (!oggContainerReader.Init()) { LastError = "Could not initialize stream"; oggContainerReader.Dispose(); return false; } if (oggContainerReader.StreamSerials.Length == 0) { LastError = "Initialization failed: No elementary streams found in input file"; oggContainerReader.Dispose(); return false; } _containerReader = oggContainerReader; int streamSerial = oggContainerReader.StreamSerials[0]; _packetProvider = oggContainerReader.GetStream(streamSerial); if (CanSeek) { GranuleCount = _packetProvider.GetGranuleCount(); PageCount = _packetProvider.GetTotalPageCount(); } QueueNextPacket(); return true; } catch (Exception ex) { LastError = "Unknown initialization error: " + ex.Message; return false; } } public void SeekTo(TimeSpan playbackTime) { if (!CanSeek) { throw new InvalidOperationException("Stream is not seekable."); } if (playbackTime < TimeSpan.Zero || playbackTime > TotalTime) { throw new ArgumentOutOfRangeException("playbackTime"); } long granulePosition = Convert.ToInt64(playbackTime.TotalSeconds * 48000.0); SeekToGranulePosition(granulePosition); } private void SeekToGranulePosition(long granulePosition) { if (!CanSeek) { throw new InvalidOperationException("Stream is not seekable."); } if (granulePosition < 0 || granulePosition > GranuleCount) { throw new ArgumentOutOfRangeException("granulePosition"); } DataPacket dataPacket = _packetProvider.FindPacket(granulePosition, GetPacketLength); if (dataPacket == null || dataPacket.IsEndOfStream) { _endOfStream = true; _nextDataPacket = null; return; } _packetProvider.SeekToPacket(dataPacket, 1); PageGranulePosition = _packetProvider.PeekNextPacket().PageGranulePosition; if (_decoder != null) { _decoder.ResetState(); } } private int GetPacketLength(DataPacket curPacket, DataPacket lastPacket) { if (lastPacket == null || curPacket.IsResync) { return 0; } if (curPacket.ReadBit()) { return 0; } if (lastPacket.ReadBit()) { return 0; } return 1; } private void QueueNextPacket() { if (_endOfStream) { return; } DataPacket nextPacket = _packetProvider.GetNextPacket(); if (nextPacket == null) { _endOfStream = true; _nextDataPacket = null; return; } PageGranulePosition = nextPacket.PageGranulePosition; PagePosition = nextPacket.PageSequenceNumber; byte[] array = new byte[nextPacket.Length]; nextPacket.Read(array, 0, nextPacket.Length); nextPacket.Done(); if (array.Length > 8 && "OpusHead".Equals(Encoding.UTF8.GetString(array, 0, 8))) { QueueNextPacket(); } else if (array.Length > 8 && "OpusTags".Equals(Encoding.UTF8.GetString(array, 0, 8))) { Tags = OpusTags.ParsePacket(array, array.Length); QueueNextPacket(); } else { _nextDataPacket = array; } } public void Close() { _containerReader?.Dispose(); } } internal class OpusOggWriteStream { private const int FRAME_SIZE_MS = 20; private const byte EARLY_FINALIZE_SEGMENT_LIMIT = 248; private IOpusEncoder _encoder; private Stream _outputStream; private Crc _crc; private int _inputChannels; private IResampler _resampler; private int _inputSampleRate; private readonly bool _leaveOpen; private int _encoderSampleRate; private short[] _opusFrame; private int _opusFrameSamples; private int _opusFrameIndex; private byte[] _currentHeader = new byte[400]; private byte[] _currentPayload = new byte[65536]; private int _headerIndex; private int _payloadIndex; private int _pageCounter; private int _logicalStreamId; private long _granulePosition; private byte _packetsInPage; private byte _lacingTableCount; private byte _maxPacketsPerPage = 248; private const int PAGE_FLAGS_POS = 5; private const int GRANULE_COUNT_POS = 6; private const int CHECKSUM_HEADER_POS = 22; private const int SEGMENT_COUNT_POS = 26; private bool _finalized; public TimeSpan MaxAudioLengthPerPage { get { return TimeSpan.FromMilliseconds(20 * _maxPacketsPerPage); } set { if (value <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException("MaxAudioLengthPerPage"); } _maxPacketsPerPage = (byte)Math.Min(248, Math.Max(1, (int)(value.TotalMilliseconds / 20.0))); } } public OpusOggWriteStream(IOpusEncoder encoder, Stream outputStream, OpusTags fileTags = null, int inputSampleRate = 0, int resamplerQuality = 5, bool leaveOpen = false) { _encoder = encoder; if (_encoder.UseDTX) { throw new ArgumentException("DTX is not currently supported in Ogg streams"); } _inputSampleRate = inputSampleRate; _leaveOpen = leaveOpen; if (_inputSampleRate == 0) { _inputSampleRate = _encoder.SampleRate; } _logicalStreamId = new Random().Next(); _encoderSampleRate = encoder.SampleRate; _inputChannels = encoder.NumChannels; _outputStream = outputStream; _opusFrameIndex = 0; _granulePosition = 0L; _opusFrameSamples = (int)((long)_encoderSampleRate * 20L / 1000); _opusFrame = new short[_opusFrameSamples * _inputChannels]; _crc = new Crc(); _resampler = ResamplerFactory.CreateResampler(_inputChannels, _inputSampleRate, _encoderSampleRate, resamplerQuality); BeginNewPage(); WriteOpusHeadPage(); WriteOpusTagsPage(fileTags); } public void WriteSamples(short[] data, int offset, int count) { if (_finalized) { throw new InvalidOperationException("Cannot write new samples to Ogg file, the output stream is already closed!"); } if (data.Length - offset < count) { throw new ArgumentOutOfRangeException("The given audio buffer claims to have " + count + " samples, but it actually only has " + (data.Length - offset)); } int num = 0; for (int num2 = Math.Min(_opusFrame.Length - _opusFrameIndex, count - num); num2 > 0; num2 = Math.Min(_opusFrame.Length - _opusFrameIndex, count - num)) { if (_inputSampleRate != _encoderSampleRate) { int in_len = (count - num) / _inputChannels; int out_len = num2 / _inputChannels; _resampler.ProcessInterleaved(MemoryExtensions.AsSpan(data, offset + num), ref in_len, MemoryExtensions.AsSpan(_opusFrame, _opusFrameIndex), ref out_len); num += in_len * _inputChannels; _opusFrameIndex += out_len * _inputChannels; } else { MemoryExtensions.AsSpan(data, offset + num, num2).CopyTo(MemoryExtensions.AsSpan(_opusFrame, _opusFrameIndex, num2)); _opusFrameIndex += num2; num += num2; } if (_opusFrameIndex == _opusFrame.Length) { int num3 = _encoder.Encode(MemoryExtensions.AsSpan(_opusFrame), _opusFrameSamples, MemoryExtensions.AsSpan(_currentPayload, _payloadIndex), _currentPayload.Length - _payloadIndex); _payloadIndex += num3; _granulePosition += 960L; int num4 = num3; while (num4 >= 255) { num4 -= 255; _currentHeader[_headerIndex++] = byte.MaxValue; _lacingTableCount++; } _currentHeader[_headerIndex++] = (byte)num4; _lacingTableCount++; _packetsInPage++; if (_packetsInPage >= _maxPacketsPerPage || _lacingTableCount > 248) { FinalizePage(); } _opusFrameIndex = 0; } } } public void WriteSamples(float[] data, int offset, int count) { if (_finalized) { throw new InvalidOperationException("Cannot write new samples to Ogg file, the output stream is already closed!"); } short[] array = new short[count]; for (int i = 0; i < count; i++) { array[i] = (short)(data[i + offset] * 32767f); } WriteSamples(array, 0, count); } public void Finish() { int num = _opusFrame.Length - _opusFrameIndex; short[] data = new short[num]; WriteSamples(data, 0, num); FinalizePage(); WriteStreamFinishedPage(); _outputStream.Flush(); if (!_leaveOpen) { _outputStream.Dispose(); } _finalized = true; } private void WriteStreamFinishedPage() { _currentHeader[_headerIndex++] = 0; _lacingTableCount++; _currentHeader[5] = 4; FinalizePage(); } private void WriteOpusHeadPage() { if (_payloadIndex != 0) { throw new InvalidOperationException("Must begin writing OpusHead on a new page!"); } _payloadIndex += WriteValueToByteBuffer("OpusHead", _currentPayload, _payloadIndex); _currentPayload[_payloadIndex++] = 1; _currentPayload[_payloadIndex++] = (byte)_inputChannels; short val = 0; _payloadIndex += WriteValueToByteBuffer(val, _currentPayload, _payloadIndex); _payloadIndex += WriteValueToByteBuffer(_encoderSampleRate, _currentPayload, _payloadIndex); short val2 = 0; _payloadIndex += WriteValueToByteBuffer(val2, _currentPayload, _payloadIndex); _currentPayload[_payloadIndex++] = 0; _currentHeader[_headerIndex++] = (byte)_payloadIndex; _lacingTableCount++; _currentHeader[5] = 2; FinalizePage(); } private void WriteOpusTagsPage(OpusTags tags = null) { if (tags == null) { tags = new OpusTags(); } if (string.IsNullOrEmpty(tags.Comment)) { tags.Comment = _encoder.GetVersionString(); } if (_payloadIndex != 0) { throw new InvalidOperationException("Must begin writing OpusTags on a new page!"); } _payloadIndex += WriteValueToByteBuffer("OpusTags", _currentPayload, _payloadIndex); int num = WriteValueToByteBuffer(tags.Comment, _currentPayload, _payloadIndex + 4); _payloadIndex += WriteValueToByteBuffer(num, _currentPayload, _payloadIndex); _payloadIndex += num; int payloadIndex = _payloadIndex; _payloadIndex += 4; int num2 = 0; foreach (KeyValuePair field in tags.Fields) { if (!string.IsNullOrEmpty(field.Key) && !string.IsNullOrEmpty(field.Value)) { num = WriteValueToByteBuffer(field.Key + "=" + field.Value, _currentPayload, _payloadIndex + 4); _payloadIndex += WriteValueToByteBuffer(num, _currentPayload, _payloadIndex); _payloadIndex += num; num2++; } } WriteValueToByteBuffer(num2, _currentPayload, payloadIndex); int num3; for (num3 = _payloadIndex; num3 >= 255; num3 -= 255) { _currentHeader[_headerIndex++] = byte.MaxValue; _lacingTableCount++; } _currentHeader[_headerIndex++] = (byte)num3; _lacingTableCount++; FinalizePage(); } private void BeginNewPage() { _headerIndex = 0; _payloadIndex = 0; _packetsInPage = 0; _lacingTableCount = 0; _headerIndex += WriteValueToByteBuffer("OggS", _currentHeader, _headerIndex); _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _headerIndex += WriteValueToByteBuffer(_granulePosition, _currentHeader, _headerIndex); _headerIndex += WriteValueToByteBuffer(_logicalStreamId, _currentHeader, _headerIndex); _headerIndex += WriteValueToByteBuffer(_pageCounter, _currentHeader, _headerIndex); _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = _lacingTableCount; _pageCounter++; } private void FinalizePage() { if (_finalized) { throw new InvalidOperationException("Cannot finalize page, the output stream is already closed!"); } if (_lacingTableCount != 0) { _currentHeader[26] = _lacingTableCount; WriteValueToByteBuffer(_granulePosition, _currentHeader, 6); _crc.Reset(); for (int i = 0; i < _headerIndex; i++) { _crc.Update(_currentHeader[i]); } for (int j = 0; j < _payloadIndex; j++) { _crc.Update(_currentPayload[j]); } WriteValueToByteBuffer(_crc.Value, _currentHeader, 22); _outputStream.Write(_currentHeader, 0, _headerIndex); _outputStream.Write(_currentPayload, 0, _payloadIndex); BeginNewPage(); } } private static int WriteValueToByteBuffer(int val, byte[] target, int targetOffset) { BinaryHelpers.Int32ToByteArrayLittleEndian(val, target, targetOffset); return 4; } private static int WriteValueToByteBuffer(long val, byte[] target, int targetOffset) { BinaryHelpers.Int64ToByteArrayLittleEndian(val, target, targetOffset); return 8; } private static int WriteValueToByteBuffer(uint val, byte[] target, int targetOffset) { BinaryHelpers.UInt32ToByteArrayLittleEndian(val, target, targetOffset); return 4; } private static int WriteValueToByteBuffer(short val, byte[] target, int targetOffset) { BinaryHelpers.Int16ToByteArrayLittleEndian(val, target, targetOffset); return 2; } private static int WriteValueToByteBuffer(string val, byte[] target, int targetOffset) { if (string.IsNullOrEmpty(val)) { return 0; } return Encoding.UTF8.GetBytes(val, 0, val.Length, target, targetOffset); } } internal class OpusRawWriteStream { private Stream _outputStream; private Crc _crc; private int _inputChannels; private readonly bool _leaveOpen; private int _inputSampleRate; private byte[] _currentHeader = new byte[400]; private byte[] _currentPayload = new byte[65536]; private int _headerIndex; private int _payloadIndex; private int _pageCounter; private int _logicalStreamId; private long _granulePosition; private byte _lacingTableCount; private const int PAGE_FLAGS_POS = 5; private const int GRANULE_COUNT_POS = 6; private const int CHECKSUM_HEADER_POS = 22; private const int SEGMENT_COUNT_POS = 26; private bool _finalized; public OpusRawWriteStream(Stream outputStream, OpusTags fileTags, int inputSampleRate, int inputNumChannels, bool leaveOpen = false) { _inputSampleRate = inputSampleRate; _logicalStreamId = new Random().Next(); _inputChannels = inputNumChannels; _leaveOpen = leaveOpen; _outputStream = outputStream; _granulePosition = 0L; _crc = new Crc(); BeginNewPage(); WriteOpusHeadPage(); WriteOpusTagsPage(fileTags); } public void WriteSinglePacket(byte[] opusPacket, int offset, int packetSize) { if (_finalized) { throw new InvalidOperationException("Cannot write new samples to Ogg file, the output stream is already closed!"); } if (opusPacket.Length - offset < packetSize) { throw new ArgumentOutOfRangeException("The given audio buffer claims to have " + packetSize + " samples, but it actually only has " + (opusPacket.Length - offset)); } Array.Copy(opusPacket, offset, _currentPayload, _payloadIndex, packetSize); _payloadIndex += packetSize; int numSamplesPerFrame = OpusPacketInfo.GetNumSamplesPerFrame(MemoryExtensions.AsSpan(opusPacket, offset), 48000); _granulePosition += numSamplesPerFrame; int num = packetSize; while (num >= 255) { num -= 255; _currentHeader[_headerIndex++] = byte.MaxValue; _lacingTableCount++; } _currentHeader[_headerIndex++] = (byte)num; _lacingTableCount++; if (_lacingTableCount > 248) { FinalizePage(); } } public void Finish() { FinalizePage(); WriteStreamFinishedPage(); _outputStream.Flush(); if (!_leaveOpen) { _outputStream.Dispose(); } _finalized = true; } private void WriteStreamFinishedPage() { _currentHeader[_headerIndex++] = 0; _lacingTableCount++; _currentHeader[5] = 4; FinalizePage(); } private void WriteOpusHeadPage() { if (_payloadIndex != 0) { throw new InvalidOperationException("Must begin writing OpusHead on a new page!"); } _payloadIndex += WriteValueToByteBuffer("OpusHead", _currentPayload, _payloadIndex); _currentPayload[_payloadIndex++] = 1; _currentPayload[_payloadIndex++] = (byte)_inputChannels; short val = 0; _payloadIndex += WriteValueToByteBuffer(val, _currentPayload, _payloadIndex); _payloadIndex += WriteValueToByteBuffer(_inputSampleRate, _currentPayload, _payloadIndex); short val2 = 0; _payloadIndex += WriteValueToByteBuffer(val2, _currentPayload, _payloadIndex); _currentPayload[_payloadIndex++] = 0; _currentHeader[_headerIndex++] = (byte)_payloadIndex; _lacingTableCount++; _currentHeader[5] = 2; FinalizePage(); } private void WriteOpusTagsPage(OpusTags tags = null) { if (tags == null) { tags = new OpusTags(); } if (string.IsNullOrEmpty(tags.Comment)) { tags.Comment = "Concentus.OggFile"; } if (_payloadIndex != 0) { throw new InvalidOperationException("Must begin writing OpusTags on a new page!"); } _payloadIndex += WriteValueToByteBuffer("OpusTags", _currentPayload, _payloadIndex); int num = WriteValueToByteBuffer(tags.Comment, _currentPayload, _payloadIndex + 4); _payloadIndex += WriteValueToByteBuffer(num, _currentPayload, _payloadIndex); _payloadIndex += num; int payloadIndex = _payloadIndex; _payloadIndex += 4; int num2 = 0; foreach (KeyValuePair field in tags.Fields) { if (!string.IsNullOrEmpty(field.Key) && !string.IsNullOrEmpty(field.Value)) { num = WriteValueToByteBuffer(field.Key + "=" + field.Value, _currentPayload, _payloadIndex + 4); _payloadIndex += WriteValueToByteBuffer(num, _currentPayload, _payloadIndex); _payloadIndex += num; num2++; } } WriteValueToByteBuffer(num2, _currentPayload, payloadIndex); int num3; for (num3 = _payloadIndex; num3 >= 255; num3 -= 255) { _currentHeader[_headerIndex++] = byte.MaxValue; _lacingTableCount++; } _currentHeader[_headerIndex++] = (byte)num3; _lacingTableCount++; FinalizePage(); } private void BeginNewPage() { _headerIndex = 0; _payloadIndex = 0; _lacingTableCount = 0; _headerIndex += WriteValueToByteBuffer("OggS", _currentHeader, _headerIndex); _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _headerIndex += WriteValueToByteBuffer(_granulePosition, _currentHeader, _headerIndex); _headerIndex += WriteValueToByteBuffer(_logicalStreamId, _currentHeader, _headerIndex); _headerIndex += WriteValueToByteBuffer(_pageCounter, _currentHeader, _headerIndex); _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = 0; _currentHeader[_headerIndex++] = _lacingTableCount; _pageCounter++; } private void FinalizePage() { if (_finalized) { throw new InvalidOperationException("Cannot finalize page, the output stream is already closed!"); } if (_lacingTableCount != 0) { _currentHeader[26] = _lacingTableCount; WriteValueToByteBuffer(_granulePosition, _currentHeader, 6); _crc.Reset(); for (int i = 0; i < _headerIndex; i++) { _crc.Update(_currentHeader[i]); } for (int j = 0; j < _payloadIndex; j++) { _crc.Update(_currentPayload[j]); } WriteValueToByteBuffer(_crc.Value, _currentHeader, 22); _outputStream.Write(_currentHeader, 0, _headerIndex); _outputStream.Write(_currentPayload, 0, _payloadIndex); BeginNewPage(); } } private static int WriteValueToByteBuffer(int val, byte[] target, int targetOffset) { Array.Copy(BitConverter.GetBytes(val), 0, target, targetOffset, 4); return 4; } private static int WriteValueToByteBuffer(long val, byte[] target, int targetOffset) { Array.Copy(BitConverter.GetBytes(val), 0, target, targetOffset, 8); return 8; } private static int WriteValueToByteBuffer(uint val, byte[] target, int targetOffset) { Array.Copy(BitConverter.GetBytes(val), 0, target, targetOffset, 4); return 4; } private static int WriteValueToByteBuffer(short val, byte[] target, int targetOffset) { Array.Copy(BitConverter.GetBytes(val), 0, target, targetOffset, 2); return 2; } private static int WriteValueToByteBuffer(string val, byte[] target, int targetOffset) { if (string.IsNullOrEmpty(val)) { return 0; } byte[] bytes = Encoding.UTF8.GetBytes(val); Array.Copy(bytes, 0, target, targetOffset, bytes.Length); return bytes.Length; } } internal class OpusTagName { public const string Title = "title"; public const string Artist = "artist"; public const string Album = "album"; } internal class OpusTags { private string _comment = string.Empty; private IDictionary _fields = new Dictionary(); public string Comment { get { return _comment; } set { _comment = value; } } public IDictionary Fields => _fields; internal static OpusTags ParsePacket(byte[] packet, int packetLength) { if (packetLength < 8) { return null; } if (!"OpusTags".Equals(Encoding.UTF8.GetString(packet, 0, 8))) { return null; } OpusTags opusTags = new OpusTags(); int num = 8; int num2 = BitConverter.ToInt32(packet, num); num += 4; if (num2 > 0) { opusTags._comment = Encoding.UTF8.GetString(packet, num, num2); num += num2; } int num3 = BitConverter.ToInt32(packet, num); num += 4; for (int i = 0; i < num3; i++) { num2 = BitConverter.ToInt32(packet, num); num += 4; if (num2 > 0) { string text = Encoding.UTF8.GetString(packet, num, num2); num += num2; int num4 = text.IndexOf('='); if (num4 > 0) { string key = text.Substring(0, num4); string value = text.Substring(num4 + 1); opusTags._fields[key] = value; } } } return opusTags; } } internal class ParameterChangeEventArgs : EventArgs { public DataPacket FirstPacket { get; private set; } public ParameterChangeEventArgs(DataPacket firstPacket) { FirstPacket = firstPacket; } } internal class StreamReadBuffer : IDisposable { internal class StreamWrapper { internal Stream Source; internal object LockObject = new object(); internal long EofOffset = long.MaxValue; internal int RefCount = 1; } private class SavedBuffer { public byte[] Buffer; public long BaseOffset; public int End; public int DiscardCount; public long VersionSaved; } private static Dictionary _lockObjects = new Dictionary(); private StreamWrapper _wrapper; private int _maxSize; private byte[] _data; private long _baseOffset; private int _end; private int _discardCount; private bool _minimalRead; private long _versionCounter; private List _savedBuffers; public bool MinimalRead { get { return _minimalRead; } set { _minimalRead = value; } } public int MaxSize { get { return _maxSize; } set { if (value < 1) { throw new ArgumentOutOfRangeException("Must be greater than zero."); } int num = 1 << (int)Math.Ceiling(Math.Log(value, 2.0)); if (num < _end) { if (num < _end - _discardCount) { throw new ArgumentOutOfRangeException("Must be greater than or equal to the number of bytes currently buffered."); } CommitDiscard(); byte[] array = new byte[num]; Buffer.BlockCopy(_data, 0, array, 0, _end); _data = array; } _maxSize = num; } } public long BaseOffset => _baseOffset + _discardCount; public int BytesFilled => _end - _discardCount; public int Length => _data.Length; internal long BufferEndOffset { get { if (_end - _discardCount > 0) { return _baseOffset + _discardCount + _maxSize; } if (_wrapper.Source.CanSeek) { return _wrapper.Source.Length; } return _baseOffset + Length; } } internal StreamReadBuffer(Stream source, int initialSize, int maxSize, bool minimalRead) { StreamWrapper value; lock (_lockObjects) { if (!_lockObjects.TryGetValue(source, out value)) { _lockObjects.Add(source, new StreamWrapper { Source = source }); value = _lockObjects[source]; if (source.CanSeek) { value.EofOffset = source.Length; } } else { value.RefCount++; } } initialSize = 2 << (int)Math.Log(initialSize - 1, 2.0); maxSize = 1 << (int)Math.Log(maxSize, 2.0); _wrapper = value; _data = new byte[initialSize]; _maxSize = maxSize; _minimalRead = minimalRead; _savedBuffers = new List(); } public void Dispose() { lock (_lockObjects) { if (--_wrapper.RefCount == 0) { _lockObjects.Remove(_wrapper.Source); } } } public int Read(long offset, byte[] buffer, int index, int count) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (index < 0 || index + count > buffer.Length) { throw new ArgumentOutOfRangeException("index"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (offset >= _wrapper.EofOffset) { return 0; } int srcOffset = EnsureAvailable(offset, ref count, isRecursion: false); Buffer.BlockCopy(_data, srcOffset, buffer, index, count); return count; } internal int ReadByte(long offset) { if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (offset >= _wrapper.EofOffset) { return -1; } int count = 1; int num = EnsureAvailable(offset, ref count, isRecursion: false); if (count == 1) { return _data[num]; } return -1; } private int EnsureAvailable(long offset, ref int count, bool isRecursion) { if (offset >= _baseOffset && offset + count < _baseOffset + _end) { return (int)(offset - _baseOffset); } if (count > _maxSize) { throw new InvalidOperationException("Not enough room in the buffer! Increase the maximum size and try again."); } _versionCounter++; if (!isRecursion) { for (int i = 0; i < _savedBuffers.Count; i++) { long num = _savedBuffers[i].BaseOffset - offset; if ((num < 0 && _savedBuffers[i].End + num > 0) || (num > 0 && count - num > 0)) { SwapBuffers(_savedBuffers[i]); return EnsureAvailable(offset, ref count, isRecursion: true); } } } while (_savedBuffers.Count > 0 && _savedBuffers[0].VersionSaved + 25 < _versionCounter) { _savedBuffers[0].Buffer = null; _savedBuffers.RemoveAt(0); } if (offset < _baseOffset && !_wrapper.Source.CanSeek) { throw new InvalidOperationException("Cannot seek before buffer on forward-only streams!"); } CalcBuffer(offset, count, out var readStart, out var readEnd); count = FillBuffer(offset, count, readStart, readEnd); return (int)(offset - _baseOffset); } private void SaveBuffer() { _savedBuffers.Add(new SavedBuffer { Buffer = _data, BaseOffset = _baseOffset, End = _end, DiscardCount = _discardCount, VersionSaved = _versionCounter }); _data = null; _end = 0; _discardCount = 0; } private void CreateNewBuffer(long offset, int count) { SaveBuffer(); _data = new byte[Math.Min(2 << (int)Math.Log(count - 1, 2.0), _maxSize)]; _baseOffset = offset; } private void SwapBuffers(SavedBuffer savedBuffer) { _savedBuffers.Remove(savedBuffer); SaveBuffer(); _data = savedBuffer.Buffer; _baseOffset = savedBuffer.BaseOffset; _end = savedBuffer.End; _discardCount = savedBuffer.DiscardCount; } private void CalcBuffer(long offset, int count, out int readStart, out int readEnd) { readStart = 0; readEnd = 0; if (offset < _baseOffset) { if (offset + _maxSize <= _baseOffset) { if (_baseOffset - (offset + _maxSize) > _maxSize) { CreateNewBuffer(offset, count); } else { EnsureBufferSize(count, copyContents: false, 0); } _baseOffset = offset; readEnd = count; } else { readEnd = (int)(offset - _baseOffset); EnsureBufferSize(Math.Min((int)(offset + _maxSize - _baseOffset), _end) - readEnd, copyContents: true, readEnd); readEnd = (int)(offset - _baseOffset) - readEnd; } } else if (offset >= _baseOffset + _maxSize) { if (offset - (_baseOffset + _maxSize) > _maxSize) { CreateNewBuffer(offset, count); } else { EnsureBufferSize(count, copyContents: false, 0); } _baseOffset = offset; readEnd = count; } else { readEnd = (int)(offset + count - _baseOffset); int num = Math.Max(readEnd - _maxSize, 0); EnsureBufferSize(readEnd - num, copyContents: true, num); readStart = _end; readEnd = (int)(offset + count - _baseOffset); } } private void EnsureBufferSize(int reqSize, bool copyContents, int copyOffset) { byte[] array = _data; if (reqSize > _data.Length) { if (reqSize > _maxSize) { if (!_wrapper.Source.CanSeek && reqSize - _discardCount > _maxSize) { throw new InvalidOperationException("Not enough room in the buffer! Increase the maximum size and try again."); } int num = reqSize - _maxSize; copyOffset += num; reqSize = _maxSize; } else { int num2; for (num2 = _data.Length; num2 < reqSize; num2 *= 2) { } reqSize = num2; } if (reqSize > _data.Length) { array = new byte[reqSize]; } } if (copyContents) { if ((copyOffset > 0 && copyOffset < _end) || (copyOffset == 0 && array != _data)) { Buffer.BlockCopy(_data, copyOffset, array, 0, _end - copyOffset); if ((_discardCount -= copyOffset) < 0) { _discardCount = 0; } } else if (copyOffset < 0 && -copyOffset < _end) { if (array != _data || _end <= -copyOffset) { Buffer.BlockCopy(_data, 0, array, -copyOffset, Math.Max(_end, Math.Min(_end, _data.Length + copyOffset))); } else { _end = copyOffset; } _discardCount = 0; } else { _end = copyOffset; _discardCount = 0; } _baseOffset += copyOffset; _end -= copyOffset; if (_end > array.Length) { _end = array.Length; } } else { _discardCount = 0; _end = 0; } _data = array; } private int FillBuffer(long offset, int count, int readStart, int readEnd) { long readOffset = _baseOffset + readStart; int readCount = readEnd - readStart; lock (_wrapper.LockObject) { readCount = PrepareStreamForRead(readCount, readOffset); ReadStream(readStart, readCount, readOffset); if (_end < readStart + readCount) { count = Math.Max(0, (int)(_baseOffset + _end - offset)); } else if (!_minimalRead && _end < _data.Length) { readCount = _data.Length - _end; readCount = PrepareStreamForRead(readCount, _baseOffset + _end); _end += _wrapper.Source.Read(_data, _end, readCount); } } return count; } private int PrepareStreamForRead(int readCount, long readOffset) { if (readCount > 0 && _wrapper.Source.Position != readOffset) { if (readOffset < _wrapper.EofOffset) { if (_wrapper.Source.CanSeek) { _wrapper.Source.Position = readOffset; } else { long num = readOffset - _wrapper.Source.Position; if (num < 0) { readCount = 0; } else { while (--num >= 0) { if (_wrapper.Source.ReadByte() == -1) { _wrapper.EofOffset = _wrapper.Source.Position; readCount = 0; break; } } } } } else { readCount = 0; } } return readCount; } private void ReadStream(int readStart, int readCount, long readOffset) { while (readCount > 0 && readOffset < _wrapper.EofOffset) { int num = _wrapper.Source.Read(_data, readStart, readCount); if (num == 0) { break; } readStart += num; readOffset += num; readCount -= num; } if (readStart > _end) { _end = readStart; } } public void DiscardThrough(long offset) { int val = (int)(offset - _baseOffset); _discardCount = Math.Max(val, _discardCount); if (_discardCount >= _data.Length) { CommitDiscard(); } } private void CommitDiscard() { if (_discardCount >= _data.Length || _discardCount >= _end) { _baseOffset += _discardCount; _end = 0; } else { Buffer.BlockCopy(_data, _discardCount, _data, 0, _end - _discardCount); _baseOffset += _discardCount; _end -= _discardCount; } _discardCount = 0; } } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 FxResources.System.Buffers { internal static class SR { } } namespace System { internal static class <2326c636-b1c4-4835-a109-42b280d74e94>SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.Buffers.SR))); internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool"); private static bool UsingResourceKeys() { return s_usingResourceKeys; } internal static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } internal static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } 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; } } } namespace System.Buffers { internal abstract class ArrayPool { private static ArrayPool s_sharedInstance; public static ArrayPool Shared { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return Volatile.Read(in s_sharedInstance) ?? EnsureSharedCreated(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static ArrayPool EnsureSharedCreated() { Interlocked.CompareExchange(ref s_sharedInstance, Create(), null); return s_sharedInstance; } public static ArrayPool Create() { return new DefaultArrayPool(); } public static ArrayPool Create(int maxArrayLength, int maxArraysPerBucket) { return new DefaultArrayPool(maxArrayLength, maxArraysPerBucket); } public abstract T[] Rent(int minimumLength); public abstract void Return(T[] array, bool clearArray = false); } [EventSource(Name = "System.Buffers.ArrayPoolEventSource")] internal sealed class ArrayPoolEventSource : EventSource { internal enum BufferAllocatedReason { Pooled, OverMaximumSize, PoolExhausted } internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource(); [Event(1, Level = EventLevel.Verbose)] internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId) { EventData* ptr = stackalloc EventData[4]; *ptr = new EventData { Size = 4, DataPointer = (IntPtr)(&bufferId) }; ptr[1] = new EventData { Size = 4, DataPointer = (IntPtr)(&bufferSize) }; ptr[2] = new EventData { Size = 4, DataPointer = (IntPtr)(&poolId) }; ptr[3] = new EventData { Size = 4, DataPointer = (IntPtr)(&bucketId) }; WriteEventCore(1, 4, ptr); } [Event(2, Level = EventLevel.Informational)] internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason) { EventData* ptr = stackalloc EventData[5]; *ptr = new EventData { Size = 4, DataPointer = (IntPtr)(&bufferId) }; ptr[1] = new EventData { Size = 4, DataPointer = (IntPtr)(&bufferSize) }; ptr[2] = new EventData { Size = 4, DataPointer = (IntPtr)(&poolId) }; ptr[3] = new EventData { Size = 4, DataPointer = (IntPtr)(&bucketId) }; ptr[4] = new EventData { Size = 4, DataPointer = (IntPtr)(&reason) }; WriteEventCore(2, 5, ptr); } [Event(3, Level = EventLevel.Verbose)] internal void BufferReturned(int bufferId, int bufferSize, int poolId) { WriteEvent(3, bufferId, bufferSize, poolId); } } internal sealed class DefaultArrayPool : ArrayPool { 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(<2326c636-b1c4-4835-a109-42b280d74e94>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; } } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } namespace FxResources.System.Memory { internal static class SR { } } namespace System { [DebuggerTypeProxy(typeof(System.MemoryDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] internal readonly struct Memory { private readonly object _object; private readonly int _index; private readonly int _length; private const int RemoveFlagsBitMask = int.MaxValue; public static Memory Empty => default(Memory); public int Length => _length & 0x7FFFFFFF; public bool IsEmpty => (_length & 0x7FFFFFFF) == 0; public Span Span { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { Span result; if (_index < 0) { result = ((MemoryManager)_object).GetSpan(); return result.Slice(_index & 0x7FFFFFFF, _length); } if (typeof(T) == typeof(char) && _object is string text) { result = new Span(Unsafe.As>(text), MemoryExtensions.StringAdjustment, text.Length); return result.Slice(_index, _length); } if (_object != null) { return new Span((T[])_object, _index, _length & 0x7FFFFFFF); } result = default(Span); return result; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory(T[] array) { if (array == null) { this = default(Memory); 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); 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); 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 manager, int length) { if (length < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } _object = manager; _index = int.MinValue; _length = length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(MemoryManager 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[] array) { return new Memory(array); } public static implicit operator Memory(ArraySegment segment) { return new Memory(segment.Array, segment.Offset, segment.Count); } public static implicit operator ReadOnlyMemory(Memory memory) { return Unsafe.As, ReadOnlyMemory>(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 Slice(int start) { int length = _length; int num = length & 0x7FFFFFFF; if ((uint)start > (uint)num) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Memory(_object, _index + start, length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory 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(_object, _index + start, length | (length2 & int.MinValue)); } public void CopyTo(Memory destination) { Span.CopyTo(destination.Span); } public bool TryCopyTo(Memory destination) { return Span.TryCopyTo(destination.Span); } public unsafe MemoryHandle Pin() { if (_index < 0) { return ((MemoryManager)_object).Pin(_index & 0x7FFFFFFF); } if (typeof(T) == typeof(char) && _object is string value) { GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned); void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer, handle); } if (_object is T[] array) { if (_length < 0) { void* pointer2 = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetReference(array)), _index); return new MemoryHandle(pointer2); } GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer3 = Unsafe.Add((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 readOnlyMemory) { return readOnlyMemory.Equals(this); } if (obj is Memory other) { return Equals(other); } return false; } public bool Equals(Memory 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 { private readonly ReadOnlyMemory _memory; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items => _memory.ToArray(); public MemoryDebugView(Memory memory) { _memory = memory; } public MemoryDebugView(ReadOnlyMemory memory) { _memory = memory; } } internal static class MemoryExtensions { internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment(); public static ReadOnlySpan Trim(this ReadOnlySpan span) { return span.TrimStart().TrimEnd(); } public static ReadOnlySpan TrimStart(this ReadOnlySpan span) { int i; for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++) { } return span.Slice(i); } public static ReadOnlySpan TrimEnd(this ReadOnlySpan span) { int num = span.Length - 1; while (num >= 0 && char.IsWhiteSpace(span[num])) { num--; } return span.Slice(0, num + 1); } public static ReadOnlySpan Trim(this ReadOnlySpan span, char trimChar) { return span.TrimStart(trimChar).TrimEnd(trimChar); } public static ReadOnlySpan TrimStart(this ReadOnlySpan span, char trimChar) { int i; for (i = 0; i < span.Length && span[i] == trimChar; i++) { } return span.Slice(i); } public static ReadOnlySpan TrimEnd(this ReadOnlySpan span, char trimChar) { int num = span.Length - 1; while (num >= 0 && span[num] == trimChar) { num--; } return span.Slice(0, num + 1); } public static ReadOnlySpan Trim(this ReadOnlySpan span, ReadOnlySpan trimChars) { return span.TrimStart(trimChars).TrimEnd(trimChars); } public static ReadOnlySpan TrimStart(this ReadOnlySpan span, ReadOnlySpan 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 TrimEnd(this ReadOnlySpan span, ReadOnlySpan 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 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(this Span span, T value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf(this Span span, ReadOnlySpan value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this Span span, T value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf(this Span span, ReadOnlySpan value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this Span span, ReadOnlySpan other) where T : IEquatable { int length = span.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(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(this Span span, ReadOnlySpan other) where T : IComparable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(ref MemoryMarshal.GetReference(other)), other.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this ReadOnlySpan span, T value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this ReadOnlySpan span, T value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOf(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this Span span, T value0, T value1) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), Unsafe.As(ref value2), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny(this Span span, ReadOnlySpan values) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this ReadOnlySpan span, T value0, T value1) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), Unsafe.As(ref value2), span.Length); } return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.IndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this Span span, T value0, T value1) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), Unsafe.As(ref value2), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny(this Span span, ReadOnlySpan values) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this ReadOnlySpan span, T value0, T value1) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value0), Unsafe.As(ref value1), Unsafe.As(ref value2), span.Length); } return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this ReadOnlySpan span, ReadOnlySpan other) where T : IEquatable { int length = span.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length == other.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(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(this ReadOnlySpan span, ReadOnlySpan other) where T : IComparable { if (typeof(T) == typeof(byte)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(ref MemoryMarshal.GetReference(other)), other.Length); } if (typeof(T) == typeof(char)) { return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(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(this Span span, ReadOnlySpan value) where T : IEquatable { int length = value.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(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(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable { int length = value.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length <= span.Length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(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(this Span span, ReadOnlySpan value) where T : IEquatable { int length = span.Length; int length2 = value.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As(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(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable { int length = span.Length; int length2 = value.Length; if (default(T) != null && IsTypeComparableAsBytes(out var size)) { if (length2 <= length) { return System.SpanHelpers.SequenceEqual(ref Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As(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(this Span 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 AsSpan(this T[] array) { return new Span(array); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span AsSpan(this T[] array, int start, int length) { return new Span(array, start, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span AsSpan(this ArraySegment segment) { return new Span(segment.Array, segment.Offset, segment.Count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span AsSpan(this ArraySegment segment, int start) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Span(segment.Array, segment.Offset + start, segment.Count - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span AsSpan(this ArraySegment 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(segment.Array, segment.Offset + start, length); } public static Memory AsMemory(this T[] array) { return new Memory(array); } public static Memory AsMemory(this T[] array, int start) { return new Memory(array, start); } public static Memory AsMemory(this T[] array, int start, int length) { return new Memory(array, start, length); } public static Memory AsMemory(this ArraySegment segment) { return new Memory(segment.Array, segment.Offset, segment.Count); } public static Memory AsMemory(this ArraySegment segment, int start) { if ((uint)start > segment.Count) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new Memory(segment.Array, segment.Offset + start, segment.Count - start); } public static Memory AsMemory(this ArraySegment 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(segment.Array, segment.Offset + start, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CopyTo(this T[] source, Span destination) { new ReadOnlySpan(source).CopyTo(destination); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CopyTo(this T[] source, Memory destination) { source.CopyTo(destination.Span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Overlaps(this Span span, ReadOnlySpan other) { return ((ReadOnlySpan)span).Overlaps(other); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Overlaps(this Span span, ReadOnlySpan other, out int elementOffset) { return ((ReadOnlySpan)span).Overlaps(other, out elementOffset); } public static bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other) { if (span.IsEmpty || other.IsEmpty) { return false; } IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other)); if (Unsafe.SizeOf() == 4) { if ((uint)(int)intPtr >= (uint)(span.Length * Unsafe.SizeOf())) { return (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf())); } return true; } if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)Unsafe.SizeOf())) { return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf())); } return true; } public static bool Overlaps(this ReadOnlySpan span, ReadOnlySpan 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() == 4) { if ((uint)(int)intPtr < (uint)(span.Length * Unsafe.SizeOf()) || (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf()))) { if ((int)intPtr % Unsafe.SizeOf() != 0) { System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); } elementOffset = (int)intPtr / Unsafe.SizeOf(); return true; } elementOffset = 0; return false; } if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)Unsafe.SizeOf()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf()))) { if ((long)intPtr % Unsafe.SizeOf() != 0L) { System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); } elementOffset = (int)((long)intPtr / Unsafe.SizeOf()); return true; } elementOffset = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this Span span, IComparable comparable) { return span.BinarySearch>(comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this Span span, TComparable comparable) where TComparable : IComparable { return BinarySearch((ReadOnlySpan)span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this Span span, T value, TComparer comparer) where TComparer : IComparer { return ((ReadOnlySpan)span).BinarySearch(value, comparer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this ReadOnlySpan span, IComparable comparable) { return MemoryExtensions.BinarySearch>(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this ReadOnlySpan span, TComparable comparable) where TComparable : IComparable { return System.SpanHelpers.BinarySearch(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this ReadOnlySpan span, T value, TComparer comparer) where TComparer : IComparer { if (comparer == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer); } System.SpanHelpers.ComparerComparable comparable = new System.SpanHelpers.ComparerComparable(value, comparer); return BinarySearch(span, comparable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsTypeComparableAsBytes(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 AsSpan(this T[] array, int start) { return Span.Create(array, start); } public static bool Contains(this ReadOnlySpan span, ReadOnlySpan value, StringComparison comparisonType) { return span.IndexOf(value, comparisonType) >= 0; } public static bool Equals(this ReadOnlySpan span, ReadOnlySpan 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 span, ReadOnlySpan other) { if (other.Length == 0) { return true; } return CompareToOrdinalIgnoreCase(span, other) == 0; } public static int CompareTo(this ReadOnlySpan span, ReadOnlySpan 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 strA, ReadOnlySpan strB) { int num = Math.Min(strA.Length, strB.Length); int num2 = num; fixed (char* reference = &MemoryMarshal.GetReference(strA)) { fixed (char* reference2 = &MemoryMarshal.GetReference(strB)) { char* ptr = reference; char* ptr2 = reference2; while (num != 0 && *ptr <= '\u007f' && *ptr2 <= '\u007f') { int num3 = *ptr; int num4 = *ptr2; if (num3 == num4) { ptr++; ptr2++; num--; continue; } if ((uint)(num3 - 97) <= 25u) { num3 -= 32; } if ((uint)(num4 - 97) <= 25u) { num4 -= 32; } if (num3 != num4) { return num3 - num4; } ptr++; ptr2++; 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 span, ReadOnlySpan value, StringComparison comparisonType) { if (comparisonType == StringComparison.Ordinal) { return span.IndexOf(value); } return span.ToString().IndexOf(value.ToString(), comparisonType); } public static int ToLower(this ReadOnlySpan source, Span 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 source, Span destination) { return source.ToLower(destination, CultureInfo.InvariantCulture); } public static int ToUpper(this ReadOnlySpan source, Span 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 source, Span destination) { return source.ToUpper(destination, CultureInfo.InvariantCulture); } public static bool EndsWith(this ReadOnlySpan span, ReadOnlySpan 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 span, ReadOnlySpan 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 AsSpan(this string text) { if (text == null) { return default(ReadOnlySpan); } return new ReadOnlySpan(Unsafe.As>(text), StringAdjustment, text.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan AsSpan(this string text, int start) { if (text == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlySpan); } if ((uint)start > (uint)text.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlySpan(Unsafe.As>(text), StringAdjustment + start * 2, text.Length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan 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); } if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlySpan(Unsafe.As>(text), StringAdjustment + start * 2, length); } public static ReadOnlyMemory AsMemory(this string text) { if (text == null) { return default(ReadOnlyMemory); } return new ReadOnlyMemory(text, 0, text.Length); } public static ReadOnlyMemory AsMemory(this string text, int start) { if (text == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(ReadOnlyMemory); } if ((uint)start > (uint)text.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory(text, start, text.Length - start); } public static ReadOnlyMemory 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); } if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory(text, start, length); } private unsafe static IntPtr MeasureStringAdjustment() { string text = "a"; fixed (char* source = text) { return Unsafe.ByteOffset(ref Unsafe.As>(text).Data, ref Unsafe.AsRef(source)); } } } internal struct MutableDecimal { public uint Flags; public uint High; public uint Low; public uint Mid; private const uint SignMask = 2147483648u; private const uint ScaleMask = 16711680u; private const int ScaleShift = 16; public bool IsNegative { get { return (Flags & 0x80000000u) != 0; } set { Flags = (Flags & 0x7FFFFFFF) | (uint)(value ? int.MinValue : 0); } } public int Scale { get { return (byte)(Flags >> 16); } set { Flags = (Flags & 0xFF00FFFFu) | (uint)(value << 16); } } } internal struct NUInt { private unsafe readonly void* _value; private unsafe NUInt(uint value) { _value = (void*)value; } private unsafe NUInt(ulong value) { _value = (void*)value; } public static implicit operator NUInt(uint value) { return new NUInt(value); } public unsafe static implicit operator IntPtr(NUInt value) { return (IntPtr)value._value; } public static explicit operator NUInt(int value) { return new NUInt((uint)value); } public unsafe static explicit operator void*(NUInt value) { return value._value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static NUInt operator *(NUInt left, NUInt right) { if (sizeof(IntPtr) != 4) { return new NUInt((ulong)left._value * (ulong)right._value); } return new NUInt((uint)((int)left._value * (int)right._value)); } } 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*)(&d))[1] >> 20) & 0x7FF; } public unsafe static ulong Mantissa(double d) { return (uint)(*(int*)(&d)) | ((ulong)(((uint*)(&d))[1] & 0xFFFFF) << 32); } public unsafe static bool Sign(double d) { return ((uint*)(&d))[1] >> 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 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(ref source); return true; } public static void DecimalToNumber(decimal value, ref NumberBuffer number) { ref MutableDecimal reference = ref Unsafe.As(ref value); Span 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 digits2 = number.Digits; int index = 0; while (--num4 >= 0) { digits2[index++] = digits[num++]; } digits2[index] = 0; } private static uint DigitsToInt(ReadOnlySpan 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 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 (((int)num3 & 0x400) != 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 Digits => new Span(Unsafe.AsPointer(ref _b0), 51); public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(ref _b0); public int NumDigits => Digits.IndexOf(0); [Conditional("DEBUG")] public void CheckConsistency() { } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append('['); stringBuilder.Append('"'); Span 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(); } } [StructLayout(LayoutKind.Sequential)] internal sealed class Pinnable { public T Data; } [DebuggerTypeProxy(typeof(System.MemoryDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] internal readonly struct ReadOnlyMemory { private readonly object _object; private readonly int _index; private readonly int _length; internal const int RemoveFlagsBitMask = int.MaxValue; public static ReadOnlyMemory Empty => default(ReadOnlyMemory); public int Length => _length & 0x7FFFFFFF; public bool IsEmpty => (_length & 0x7FFFFFFF) == 0; public ReadOnlySpan Span { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (_index < 0) { return ((MemoryManager)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length); } ReadOnlySpan result; if (typeof(T) == typeof(char) && _object is string text) { result = new ReadOnlySpan(Unsafe.As>(text), MemoryExtensions.StringAdjustment, text.Length); return result.Slice(_index, _length); } if (_object != null) { return new ReadOnlySpan((T[])_object, _index, _length & 0x7FFFFFFF); } result = default(ReadOnlySpan); return result; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory(T[] array) { if (array == null) { this = default(ReadOnlyMemory); 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); 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[] array) { return new ReadOnlyMemory(array); } public static implicit operator ReadOnlyMemory(ArraySegment segment) { return new ReadOnlyMemory(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 Slice(int start) { int length = _length; int num = length & 0x7FFFFFFF; if ((uint)start > (uint)num) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return new ReadOnlyMemory(_object, _index + start, length - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory 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(_object, _index + start, length | (length2 & int.MinValue)); } public void CopyTo(Memory destination) { Span.CopyTo(destination.Span); } public bool TryCopyTo(Memory destination) { return Span.TryCopyTo(destination.Span); } public unsafe MemoryHandle Pin() { if (_index < 0) { return ((MemoryManager)_object).Pin(_index & 0x7FFFFFFF); } if (typeof(T) == typeof(char) && _object is string value) { GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned); void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), _index); return new MemoryHandle(pointer, handle); } if (_object is T[] array) { if (_length < 0) { void* pointer2 = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetReference(array)), _index); return new MemoryHandle(pointer2); } GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned); void* pointer3 = Unsafe.Add((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 other) { return Equals(other); } if (obj is Memory memory) { return Equals(memory); } return false; } public bool Equals(ReadOnlyMemory 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<>))] internal readonly ref struct ReadOnlySpan { public ref struct Enumerator { private readonly ReadOnlySpan _span; private int _index; public ref readonly T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _span[_index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Enumerator(ReadOnlySpan 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 _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; public int Length => _length; public bool IsEmpty => _length == 0; public static ReadOnlySpan Empty => default(ReadOnlySpan); 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(byteOffset.ToPointer()), index); } return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index); } } internal Pinnable Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; public static bool operator !=(ReadOnlySpan left, ReadOnlySpan 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(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.NotSupported_CannotCallEqualsOnSpan); } [Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")] [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.NotSupported_CannotCallGetHashCodeOnSpan); } public static implicit operator ReadOnlySpan(T[] array) { return new ReadOnlySpan(array); } public static implicit operator ReadOnlySpan(ArraySegment segment) { return new ReadOnlySpan(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); return; } _length = array.Length; _pinnable = Unsafe.As>(array); _byteOffset = System.SpanHelpers.PerTypeValues.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); return; } if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } _length = length; _pinnable = Unsafe.As>(array); _byteOffset = System.SpanHelpers.PerTypeValues.ArrayAdjustment.Add(start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public unsafe ReadOnlySpan(void* pointer, int length) { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { 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 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(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } return ref Unsafe.AsRef(null); } public void CopyTo(Span destination) { if (!TryCopyTo(destination)) { System.ThrowHelper.ThrowArgumentException_DestinationTooShort(); } } public bool TryCopyTo(Span 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 left, ReadOnlySpan 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(_pinnable); if (obj is string text && _length == text.Length) { return text; } } fixed (char* value = &Unsafe.As(ref DangerousGetPinnableReference())) { return new string(value, 0, _length); } } return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan Slice(int start) { if ((uint)start > (uint)_length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add(start); int length = _length - start; return new ReadOnlySpan(_pinnable, byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan 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(start); return new ReadOnlySpan(_pinnable, byteOffset, length); } public T[] ToArray() { if (_length == 0) { return System.SpanHelpers.PerTypeValues.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(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } } internal readonly struct SequencePosition : IEquatable { 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 <27c7dfb4-b639-4500-8914-8d6e6caca8cb>HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer); } } [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] internal readonly ref struct Span { public ref struct Enumerator { private readonly Span _span; private int _index; public ref T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _span[_index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Enumerator(Span 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 _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; public int Length => _length; public bool IsEmpty => _length == 0; public static Span Empty => default(Span); 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(byteOffset.ToPointer()), index); } return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index); } } internal Pinnable Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; public static bool operator !=(Span left, Span 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(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.NotSupported_CannotCallEqualsOnSpan); } [Obsolete("GetHashCode() on Span will always throw an exception.")] [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.NotSupported_CannotCallGetHashCodeOnSpan); } public static implicit operator Span(T[] array) { return new Span(array); } public static implicit operator Span(ArraySegment segment) { return new Span(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); return; } if (default(T) == null && array.GetType() != typeof(T[])) { System.ThrowHelper.ThrowArrayTypeMismatchException(); } _length = array.Length; _pinnable = Unsafe.As>(array); _byteOffset = System.SpanHelpers.PerTypeValues.ArrayAdjustment; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Span Create(T[] array, int start) { if (array == null) { if (start != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } return default(Span); } 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.ArrayAdjustment.Add(start); int length = array.Length - start; return new Span(Unsafe.As>(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); 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>(array); _byteOffset = System.SpanHelpers.PerTypeValues.ArrayAdjustment.Add(start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public unsafe Span(void* pointer, int length) { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { 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 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(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } return ref Unsafe.AsRef(null); } public unsafe void Clear() { int length = _length; if (length == 0) { return; } UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf()); if ((Unsafe.SizeOf() & (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(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength); } } else if (System.SpanHelpers.IsReferenceOrContainsReferences()) { UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf() / sizeof(IntPtr)); System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As(ref DangerousGetPinnableReference()), pointerSizeLength); } else { System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As(ref DangerousGetPinnableReference()), byteLength); } } public unsafe void Fill(T value) { int length = _length; if (length == 0) { return; } if (Unsafe.SizeOf() == 1) { byte value2 = Unsafe.As(ref value); if (_pinnable == null) { IntPtr byteOffset = _byteOffset; Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length); } else { Unsafe.InitBlockUnaligned(ref Unsafe.As(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 destination) { if (!TryCopyTo(destination)) { System.ThrowHelper.ThrowArgumentException_DestinationTooShort(); } } public bool TryCopyTo(Span 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 left, Span right) { if (left._length == right._length) { return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference()); } return false; } public static implicit operator ReadOnlySpan(Span span) { return new ReadOnlySpan(span._pinnable, span._byteOffset, span._length); } public unsafe override string ToString() { if (typeof(T) == typeof(char)) { fixed (char* value = &Unsafe.As(ref DangerousGetPinnableReference())) { return new string(value, 0, _length); } } return $"System.Span<{typeof(T).Name}>[{_length}]"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span Slice(int start) { if ((uint)start > (uint)_length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } IntPtr byteOffset = _byteOffset.Add(start); int length = _length - start; return new Span(_pinnable, byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span 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(start); return new Span(_pinnable, byteOffset, length); } public T[] ToArray() { if (_length == 0) { return System.SpanHelpers.PerTypeValues.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(byteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } } internal sealed class SpanDebugView { private readonly T[] _array; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items => _array; public SpanDebugView(Span span) { _array = span.ToArray(); } public SpanDebugView(ReadOnlySpan span) { _array = span.ToArray(); } } internal static class SpanHelpers { internal struct ComparerComparable : IComparable where TComparer : IComparer { 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 { 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>(array).Data, ref array[0]); } } private const ulong XorPowerOfTwoToHighByte = 283686952306184uL; private const ulong XorPowerOfTwoToHighChar = 4295098372uL; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch(this ReadOnlySpan span, TComparable comparable) where TComparable : IComparable { if (comparable == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable); } return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable); } public static int BinarySearch(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable { 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.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)((Vector.Count - num) & (Vector.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.Count - 1)); Vector vector = GetVector(value); for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector.Count) { Vector vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr))); if (!Vector.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.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)(((length & (Vector.Count - 1)) + num) & (Vector.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 != Unsafe.AddByteOffset(ref searchSpace, intPtr)) { continue; } goto IL_0254; } if (Vector.IsHardwareAccelerated && (void*)intPtr != null) { intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector.Count - 1)); Vector vector = GetVector(value); for (; (nuint)(void*)intPtr2 > (nuint)(Vector.Count - 1); intPtr2 -= Vector.Count) { Vector vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector.Count))); if (Vector.Zero.Equals(vector2)) { intPtr -= Vector.Count; continue; } return (int)intPtr - Vector.Count + LocateLastFoundByte(vector2); } if ((void*)intPtr != null) { intPtr2 = intPtr; continue; } } return -1; IL_0254: return (int)(void*)intPtr; IL_026a: return (int)(void*)(intPtr + 2); IL_0278: return (int)(void*)(intPtr + 3); IL_025c: return (int)(void*)(intPtr + 1); } return (int)(void*)(intPtr + 7); } public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)((Vector.Count - num) & (Vector.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2) { goto IL_02ff; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2) { goto IL_0307; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2) { goto IL_0315; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num2 || value1 == num2) { break; } intPtr += 8; continue; } return (int)(void*)(intPtr + 6); } return (int)(void*)(intPtr + 5); } return (int)(void*)(intPtr + 4); } goto IL_0323; } if ((nuint)(void*)intPtr2 >= (nuint)4u) { intPtr2 -= 4; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2) { goto IL_02ff; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2) { goto IL_0307; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2) { goto IL_0315; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num2 || value1 == num2) { goto IL_0323; } intPtr += 4; } while ((void*)intPtr2 != null) { intPtr2 -= 1; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2) { intPtr += 1; continue; } goto IL_02ff; } if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) { intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector.Count - 1)); Vector vector = GetVector(value0); Vector vector2 = GetVector(value1); for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector.Count) { Vector left = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)); Vector vector3 = Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)); if (!Vector.Zero.Equals(vector3)) { return (int)(void*)intPtr + LocateFirstFoundByte(vector3); } } if ((int)(void*)intPtr < length) { intPtr2 = (IntPtr)(length - (int)(void*)intPtr); continue; } } return -1; IL_02ff: return (int)(void*)intPtr; IL_0315: return (int)(void*)(intPtr + 2); IL_0307: return (int)(void*)(intPtr + 1); IL_0323: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)((Vector.Count - num) & (Vector.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_0393; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_039b; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03a9; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num2 || value1 == num2 || value2 == num2) { break; } intPtr += 8; continue; } return (int)(void*)(intPtr + 6); } return (int)(void*)(intPtr + 5); } return (int)(void*)(intPtr + 4); } goto IL_03b7; } if ((nuint)(void*)intPtr2 >= (nuint)4u) { intPtr2 -= 4; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_0393; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_039b; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03a9; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03b7; } intPtr += 4; } while ((void*)intPtr2 != null) { intPtr2 -= 1; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2 && value2 != num2) { intPtr += 1; continue; } goto IL_0393; } if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) { intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector.Count - 1)); Vector vector = GetVector(value0); Vector vector2 = GetVector(value1); Vector vector3 = GetVector(value2); for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector.Count) { Vector left = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)); Vector vector4 = Vector.BitwiseOr(Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)), Vector.Equals(left, vector3)); if (!Vector.Zero.Equals(vector4)) { return (int)(void*)intPtr + LocateFirstFoundByte(vector4); } } if ((int)(void*)intPtr < length) { intPtr2 = (IntPtr)(length - (int)(void*)intPtr); continue; } } return -1; IL_0393: return (int)(void*)intPtr; IL_039b: return (int)(void*)(intPtr + 1); IL_03b7: return (int)(void*)(intPtr + 3); IL_03a9: return (int)(void*)(intPtr + 2); } return (int)(void*)(intPtr + 7); } public unsafe static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)(((length & (Vector.Count - 1)) + num) & (Vector.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; intPtr -= 8; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num2 || value1 == num2) { break; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 != num2 && value1 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2) { continue; } goto IL_0314; } goto IL_031c; } goto IL_032a; } goto IL_0338; } 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; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num2 || value1 == num2) { goto IL_0338; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2) { goto IL_032a; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2) { goto IL_031c; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2) { goto IL_0314; } } while ((void*)intPtr2 != null) { intPtr2 -= 1; intPtr -= 1; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2) { continue; } goto IL_0314; } if (Vector.IsHardwareAccelerated && (void*)intPtr != null) { intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector.Count - 1)); Vector vector = GetVector(value0); Vector vector2 = GetVector(value1); for (; (nuint)(void*)intPtr2 > (nuint)(Vector.Count - 1); intPtr2 -= Vector.Count) { Vector left = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector.Count)); Vector vector3 = Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)); if (Vector.Zero.Equals(vector3)) { intPtr -= Vector.Count; continue; } return (int)intPtr - Vector.Count + LocateLastFoundByte(vector3); } if ((void*)intPtr != null) { intPtr2 = intPtr; continue; } } return -1; IL_0314: return (int)(void*)intPtr; IL_0338: return (int)(void*)(intPtr + 3); IL_031c: return (int)(void*)(intPtr + 1); IL_032a: return (int)(void*)(intPtr + 2); } return (int)(void*)(intPtr + 7); } public unsafe static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); intPtr2 = (IntPtr)(((length & (Vector.Count - 1)) + num) & (Vector.Count - 1)); } while (true) { if ((nuint)(void*)intPtr2 >= (nuint)8u) { intPtr2 -= 8; intPtr -= 8; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num2 || value1 == num2 || value2 == num2) { break; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 != num2 && value1 != num2 && value2 != num2) { num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2 && value2 != num2) { continue; } goto IL_03ab; } goto IL_03b3; } goto IL_03c1; } goto IL_03cf; } 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; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03cf; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03c1; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03b3; } num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num2 || value1 == num2 || value2 == num2) { goto IL_03ab; } } while ((void*)intPtr2 != null) { intPtr2 -= 1; intPtr -= 1; uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num2 && value1 != num2 && value2 != num2) { continue; } goto IL_03ab; } if (Vector.IsHardwareAccelerated && (void*)intPtr != null) { intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector.Count - 1)); Vector vector = GetVector(value0); Vector vector2 = GetVector(value1); Vector vector3 = GetVector(value2); for (; (nuint)(void*)intPtr2 > (nuint)(Vector.Count - 1); intPtr2 -= Vector.Count) { Vector left = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector.Count)); Vector vector4 = Vector.BitwiseOr(Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)), Vector.Equals(left, vector3)); if (Vector.Zero.Equals(vector4)) { intPtr -= Vector.Count; continue; } return (int)intPtr - Vector.Count + LocateLastFoundByte(vector4); } if ((void*)intPtr != null) { intPtr2 = intPtr; continue; } } return -1; IL_03ab: return (int)(void*)intPtr; IL_03cf: return (int)(void*)(intPtr + 3); IL_03c1: return (int)(void*)(intPtr + 2); IL_03b3: return (int)(void*)(intPtr + 1); } return (int)(void*)(intPtr + 7); } public unsafe static bool SequenceEqual(ref byte first, ref byte second, NUInt length) { if (Unsafe.AreSame(ref first, ref second)) { goto IL_013d; } IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)(void*)length; if (Vector.IsHardwareAccelerated && (nuint)(void*)intPtr2 >= (nuint)Vector.Count) { intPtr2 -= Vector.Count; while (true) { if ((void*)intPtr2 > (void*)intPtr) { if (Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref second, intPtr))) { break; } intPtr += Vector.Count; continue; } return Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref first, intPtr2)) == Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref second, intPtr2)); } } else { if ((nuint)(void*)intPtr2 < (nuint)sizeof(UIntPtr)) { while ((void*)intPtr2 > (void*)intPtr) { if (Unsafe.AddByteOffset(ref first, intPtr) == Unsafe.AddByteOffset(ref second, intPtr)) { intPtr += 1; continue; } goto IL_013f; } goto IL_013d; } intPtr2 -= sizeof(UIntPtr); while (true) { if ((void*)intPtr2 > (void*)intPtr) { if (Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, intPtr))) { break; } intPtr += sizeof(UIntPtr); continue; } return Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, intPtr2)) == Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, intPtr2)); } } goto IL_013f; IL_013f: return false; IL_013d: return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundByte(Vector match) { Vector vector = Vector.AsVectorUInt64(match); ulong num = 0uL; int i; for (i = 0; i < Vector.Count; i++) { num = vector[i]; if (num != 0L) { break; } } return i * 8 + LocateFirstFoundByte(num); } public unsafe static int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) { if (!Unsafe.AreSame(ref first, ref second)) { IntPtr intPtr = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); IntPtr intPtr2 = (IntPtr)0; IntPtr intPtr3 = (IntPtr)(void*)intPtr; if (Vector.IsHardwareAccelerated && (nuint)(void*)intPtr3 > (nuint)Vector.Count) { intPtr3 -= Vector.Count; for (; (void*)intPtr3 > (void*)intPtr2 && !(Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref first, intPtr2)) != Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref second, intPtr2))); intPtr2 += Vector.Count) { } } else if ((nuint)(void*)intPtr3 > (nuint)sizeof(UIntPtr)) { intPtr3 -= sizeof(UIntPtr); for (; (void*)intPtr3 > (void*)intPtr2 && !(Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref first, intPtr2)) != Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref second, intPtr2))); intPtr2 += sizeof(UIntPtr)) { } } for (; (void*)intPtr > (void*)intPtr2; intPtr2 += 1) { int num = Unsafe.AddByteOffset(ref first, intPtr2).CompareTo(Unsafe.AddByteOffset(ref second, intPtr2)); if (num != 0) { return num; } } } return firstLength - secondLength; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundByte(Vector match) { Vector vector = Vector.AsVectorUInt64(match); ulong num = 0uL; int num2; for (num2 = Vector.Count - 1; num2 >= 0; num2--) { num = vector[num2]; if (num != 0L) { break; } } return num2 * 8 + LocateLastFoundByte(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundByte(ulong match) { ulong num = match ^ (match - 1); return (int)(num * 283686952306184L >> 57); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundByte(ulong match) { int num = 7; while ((long)match > 0L) { match <<= 8; num--; } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector GetVector(byte vectorByte) { return Vector.AsVectorByte(new Vector((uint)(vectorByte * 16843009))); } public unsafe static int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) { int result = firstLength - secondLength; if (!Unsafe.AreSame(ref first, ref second)) { IntPtr intPtr = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); IntPtr intPtr2 = (IntPtr)0; if ((nuint)(void*)intPtr >= (nuint)(sizeof(UIntPtr) / 2)) { if (Vector.IsHardwareAccelerated && (nuint)(void*)intPtr >= (nuint)Vector.Count) { IntPtr intPtr3 = intPtr - Vector.Count; while (!(Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref first, intPtr2))) != Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref second, intPtr2))))) { intPtr2 += Vector.Count; if ((void*)intPtr3 < (void*)intPtr2) { break; } } } for (; (void*)intPtr >= (void*)(intPtr2 + sizeof(UIntPtr) / 2) && !(Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref first, intPtr2))) != Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, intPtr2)))); intPtr2 += sizeof(UIntPtr) / 2) { } } if (sizeof(UIntPtr) > 4 && (void*)intPtr >= (void*)(intPtr2 + 2) && Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref first, intPtr2))) == Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, intPtr2)))) { intPtr2 += 2; } for (; (void*)intPtr2 < (void*)intPtr; intPtr2 += 1) { int num = Unsafe.Add(ref first, intPtr2).CompareTo(Unsafe.Add(ref second, intPtr2)); if (num != 0) { return num; } } } return result; } public unsafe static int IndexOf(ref char searchSpace, char value, int length) { fixed (char* ptr = &searchSpace) { char* ptr2 = ptr; char* ptr3 = ptr2 + length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { int num = ((int)ptr2 & (Unsafe.SizeOf>() - 1)) / 2; length = (Vector.Count - num) & (Vector.Count - 1); } while (true) { if (length >= 4) { length -= 4; if (*ptr2 == value) { break; } if (ptr2[1] != value) { if (ptr2[2] != value) { if (ptr2[3] != value) { ptr2 += 4; continue; } ptr2++; } ptr2++; } ptr2++; break; } while (length > 0) { length--; if (*ptr2 == value) { goto end_IL_0079; } ptr2++; } if (Vector.IsHardwareAccelerated && ptr2 < ptr3) { length = (int)((ptr3 - ptr2) & ~(Vector.Count - 1)); Vector left = new Vector(value); while (length > 0) { Vector vector = Vector.Equals(left, Unsafe.Read>(ptr2)); if (Vector.Zero.Equals(vector)) { ptr2 += Vector.Count; length -= Vector.Count; continue; } return (int)(ptr2 - ptr) + LocateFirstFoundChar(vector); } if (ptr2 < ptr3) { length = (int)(ptr3 - ptr2); continue; } } return -1; continue; end_IL_0079: break; } return (int)(ptr2 - ptr); } } public unsafe static int LastIndexOf(ref char searchSpace, char value, int length) { fixed (char* ptr = &searchSpace) { char* ptr2 = ptr + length; char* ptr3 = ptr; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { length = ((int)ptr2 & (Unsafe.SizeOf>() - 1)) / 2; } while (true) { if (length >= 4) { length -= 4; ptr2 -= 4; if (ptr2[3] == value) { break; } if (ptr2[2] != value) { if (ptr2[1] != value) { if (*ptr2 != value) { continue; } goto IL_011d; } return (int)(ptr2 - ptr3) + 1; } return (int)(ptr2 - ptr3) + 2; } while (length > 0) { length--; ptr2--; if (*ptr2 != value) { continue; } goto IL_011d; } if (Vector.IsHardwareAccelerated && ptr2 > ptr3) { length = (int)((ptr2 - ptr3) & ~(Vector.Count - 1)); Vector left = new Vector(value); while (length > 0) { char* ptr4 = ptr2 - Vector.Count; Vector vector = Vector.Equals(left, Unsafe.Read>(ptr4)); if (Vector.Zero.Equals(vector)) { ptr2 -= Vector.Count; length -= Vector.Count; continue; } return (int)(ptr4 - ptr3) + LocateLastFoundChar(vector); } if (ptr2 > ptr3) { length = (int)(ptr2 - ptr3); continue; } } return -1; IL_011d: return (int)(ptr2 - ptr3); } return (int)(ptr2 - ptr3) + 3; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundChar(Vector match) { Vector vector = Vector.AsVectorUInt64(match); ulong num = 0uL; int i; for (i = 0; i < Vector.Count; i++) { num = vector[i]; if (num != 0L) { break; } } return i * 4 + LocateFirstFoundChar(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundChar(ulong match) { ulong num = match ^ (match - 1); return (int)(num * 4295098372L >> 49); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundChar(Vector match) { Vector vector = Vector.AsVectorUInt64(match); ulong num = 0uL; int num2; for (num2 = Vector.Count - 1; num2 >= 0; num2--) { num = vector[num2]; if (num != 0L) { break; } } return num2 * 4 + LocateLastFoundChar(num); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateLastFoundChar(ulong match) { int num = 3; while ((long)match > 0L) { match <<= 16; num--; } return num; } public unsafe static void CopyTo(ref T dst, int dstLength, ref T src, int srcLength) { IntPtr intPtr = Unsafe.ByteOffset(ref src, ref Unsafe.Add(ref src, srcLength)); IntPtr intPtr2 = Unsafe.ByteOffset(ref dst, ref Unsafe.Add(ref dst, dstLength)); IntPtr intPtr3 = Unsafe.ByteOffset(ref src, ref dst); bool num; if (sizeof(IntPtr) != 4) { if ((ulong)(long)intPtr3 >= (ulong)(long)intPtr) { num = (ulong)(long)intPtr3 > (ulong)(-(long)intPtr2); goto IL_006f; } } else if ((uint)(int)intPtr3 >= (uint)(int)intPtr) { num = (uint)(int)intPtr3 > (uint)(-(int)intPtr2); goto IL_006f; } goto IL_00de; IL_006f: if (!num && !IsReferenceOrContainsReferences()) { ref byte source = ref Unsafe.As(ref dst); ref byte source2 = ref Unsafe.As(ref src); ulong num2 = (ulong)(long)intPtr; uint num4; for (ulong num3 = 0uL; num3 < num2; num3 += num4) { num4 = (uint)((num2 - num3 > uint.MaxValue) ? uint.MaxValue : (num2 - num3)); Unsafe.CopyBlock(ref Unsafe.Add(ref source, (IntPtr)(long)num3), ref Unsafe.Add(ref source2, (IntPtr)(long)num3), num4); } return; } goto IL_00de; IL_00de: bool flag = ((sizeof(IntPtr) == 4) ? ((uint)(int)intPtr3 > (uint)(-(int)intPtr2)) : ((ulong)(long)intPtr3 > (ulong)(-(long)intPtr2))); int num5 = (flag ? 1 : (-1)); int num6 = ((!flag) ? (srcLength - 1) : 0); int i; for (i = 0; i < (srcLength & -8); i += 8) { Unsafe.Add(ref dst, num6) = Unsafe.Add(ref src, num6); Unsafe.Add(ref dst, num6 + num5) = Unsafe.Add(ref src, num6 + num5); Unsafe.Add(ref dst, num6 + num5 * 2) = Unsafe.Add(ref src, num6 + num5 * 2); Unsafe.Add(ref dst, num6 + num5 * 3) = Unsafe.Add(ref src, num6 + num5 * 3); Unsafe.Add(ref dst, num6 + num5 * 4) = Unsafe.Add(ref src, num6 + num5 * 4); Unsafe.Add(ref dst, num6 + num5 * 5) = Unsafe.Add(ref src, num6 + num5 * 5); Unsafe.Add(ref dst, num6 + num5 * 6) = Unsafe.Add(ref src, num6 + num5 * 6); Unsafe.Add(ref dst, num6 + num5 * 7) = Unsafe.Add(ref src, num6 + num5 * 7); num6 += num5 * 8; } if (i < (srcLength & -4)) { Unsafe.Add(ref dst, num6) = Unsafe.Add(ref src, num6); Unsafe.Add(ref dst, num6 + num5) = Unsafe.Add(ref src, num6 + num5); Unsafe.Add(ref dst, num6 + num5 * 2) = Unsafe.Add(ref src, num6 + num5 * 2); Unsafe.Add(ref dst, num6 + num5 * 3) = Unsafe.Add(ref src, num6 + num5 * 3); num6 += num5 * 4; i += 4; } for (; i < srcLength; i++) { Unsafe.Add(ref dst, num6) = Unsafe.Add(ref src, num6); num6 += num5; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static IntPtr Add(this IntPtr start, int index) { if (sizeof(IntPtr) == 4) { uint num = (uint)(index * Unsafe.SizeOf()); return (IntPtr)((byte*)(void*)start + num); } ulong num2 = (ulong)index * (ulong)Unsafe.SizeOf(); return (IntPtr)((byte*)(void*)start + num2); } public static bool IsReferenceOrContainsReferences() { return PerTypeValues.IsReferenceOrContainsReferences; } private static bool IsReferenceOrContainsReferencesCore(Type type) { if (type.GetTypeInfo().IsPrimitive) { return false; } if (!type.GetTypeInfo().IsValueType) { return true; } Type underlyingType = Nullable.GetUnderlyingType(type); if (underlyingType != null) { type = underlyingType; } if (type.GetTypeInfo().IsEnum) { return false; } foreach (FieldInfo declaredField in type.GetTypeInfo().DeclaredFields) { if (!declaredField.IsStatic && IsReferenceOrContainsReferencesCore(declaredField.FieldType)) { return true; } } return false; } public unsafe static void ClearLessThanPointerSized(byte* ptr, UIntPtr byteLength) { if (sizeof(UIntPtr) == 4) { Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteLength); return; } ulong num = (ulong)byteLength; uint num2 = (uint)(num & 0xFFFFFFFFu); Unsafe.InitBlockUnaligned(ptr, 0, num2); num -= num2; ptr += num2; while (num != 0) { num2 = (uint)((num >= uint.MaxValue) ? uint.MaxValue : num); Unsafe.InitBlockUnaligned(ptr, 0, num2); ptr += num2; num -= num2; } } public unsafe static void ClearLessThanPointerSized(ref byte b, UIntPtr byteLength) { if (sizeof(UIntPtr) == 4) { Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength); return; } ulong num = (ulong)byteLength; uint num2 = (uint)(num & 0xFFFFFFFFu); Unsafe.InitBlockUnaligned(ref b, 0, num2); num -= num2; long num3 = num2; while (num != 0) { num2 = (uint)((num >= uint.MaxValue) ? uint.MaxValue : num); Unsafe.InitBlockUnaligned(ref Unsafe.Add(ref b, (IntPtr)num3), 0, num2); num3 += num2; num -= num2; } } public unsafe static void ClearPointerSizedWithoutReferences(ref byte b, UIntPtr byteLength) { IntPtr zero; for (zero = IntPtr.Zero; zero.LessThanEqual(byteLength - sizeof(Reg64)); zero += sizeof(Reg64)) { Unsafe.As(ref Unsafe.Add(ref b, zero)) = default(Reg64); } if (zero.LessThanEqual(byteLength - sizeof(Reg32))) { Unsafe.As(ref Unsafe.Add(ref b, zero)) = default(Reg32); zero += sizeof(Reg32); } if (zero.LessThanEqual(byteLength - sizeof(Reg16))) { Unsafe.As(ref Unsafe.Add(ref b, zero)) = default(Reg16); zero += sizeof(Reg16); } if (zero.LessThanEqual(byteLength - 8)) { Unsafe.As(ref Unsafe.Add(ref b, zero)) = 0L; zero += 8; } if (sizeof(IntPtr) == 4 && zero.LessThanEqual(byteLength - 4)) { Unsafe.As(ref Unsafe.Add(ref b, zero)) = 0; zero += 4; } } public static void ClearPointerSizedWithReferences(ref IntPtr ip, UIntPtr pointerSizeLength) { IntPtr intPtr = IntPtr.Zero; IntPtr zero = IntPtr.Zero; while ((zero = intPtr + 8).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 2) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 3) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 4) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 5) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 6) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 7) = default(IntPtr); intPtr = zero; } if ((zero = intPtr + 4).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 2) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 3) = default(IntPtr); intPtr = zero; } if ((zero = intPtr + 2).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); intPtr = zero; } if ((intPtr + 1).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr) = default(IntPtr); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe static bool LessThanEqual(this IntPtr index, UIntPtr length) { if (sizeof(UIntPtr) != 4) { return (long)index <= (long)(ulong)length; } return (int)index <= (int)(uint)length; } public static int IndexOf(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable { if (valueLength == 0) { return 0; } T value2 = value; ref T 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 unsafe static int IndexOf(ref T searchSpace, T value, int length) where T : IEquatable { IntPtr intPtr = (IntPtr)0; while (true) { T val; if (length >= 8) { length -= 8; ref T reference = ref value; val = default(T); if (val == null) { val = reference; reference = ref val; } T other = Unsafe.Add(ref searchSpace, intPtr); if (!reference.Equals(other)) { ref T reference2 = ref value; val = default(T); if (val == null) { val = reference2; reference2 = ref val; } T other2 = Unsafe.Add(ref searchSpace, intPtr + 1); if (reference2.Equals(other2)) { goto IL_0345; } ref T reference3 = ref value; val = default(T); if (val == null) { val = reference3; reference3 = ref val; } T other3 = Unsafe.Add(ref searchSpace, intPtr + 2); if (reference3.Equals(other3)) { goto IL_0353; } ref T reference4 = ref value; val = default(T); if (val == null) { val = reference4; reference4 = ref val; } T other4 = Unsafe.Add(ref searchSpace, intPtr + 3); if (!reference4.Equals(other4)) { ref T reference5 = ref value; val = default(T); if (val == null) { val = reference5; reference5 = ref val; } T other5 = Unsafe.Add(ref searchSpace, intPtr + 4); if (!reference5.Equals(other5)) { ref T reference6 = ref value; val = default(T); if (val == null) { val = reference6; reference6 = ref val; } T other6 = Unsafe.Add(ref searchSpace, intPtr + 5); if (!reference6.Equals(other6)) { ref T reference7 = ref value; val = default(T); if (val == null) { val = reference7; reference7 = ref val; } T other7 = Unsafe.Add(ref searchSpace, intPtr + 6); if (!reference7.Equals(other7)) { ref T reference8 = ref value; val = default(T); if (val == null) { val = reference8; reference8 = ref val; } T other8 = Unsafe.Add(ref searchSpace, intPtr + 7); if (reference8.Equals(other8)) { break; } intPtr += 8; continue; } return (int)(void*)(intPtr + 6); } return (int)(void*)(intPtr + 5); } return (int)(void*)(intPtr + 4); } goto IL_0361; } } else { if (length >= 4) { length -= 4; ref T reference9 = ref value; val = default(T); if (val == null) { val = reference9; reference9 = ref val; } T other9 = Unsafe.Add(ref searchSpace, intPtr); if (reference9.Equals(other9)) { goto IL_033d; } ref T reference10 = ref value; val = default(T); if (val == null) { val = reference10; reference10 = ref val; } T other10 = Unsafe.Add(ref searchSpace, intPtr + 1); if (reference10.Equals(other10)) { goto IL_0345; } ref T reference11 = ref value; val = default(T); if (val == null) { val = reference11; reference11 = ref val; } T other11 = Unsafe.Add(ref searchSpace, intPtr + 2); if (reference11.Equals(other11)) { goto IL_0353; } ref T reference12 = ref value; val = default(T); if (val == null) { val = reference12; reference12 = ref val; } T other12 = Unsafe.Add(ref searchSpace, intPtr + 3); if (reference12.Equals(other12)) { goto IL_0361; } intPtr += 4; } while (true) { if (length > 0) { ref T reference13 = ref value; val = default(T); if (val == null) { val = reference13; reference13 = ref val; } T other13 = Unsafe.Add(ref searchSpace, intPtr); if (reference13.Equals(other13)) { break; } intPtr += 1; length--; continue; } return -1; } } goto IL_033d; IL_033d: return (int)(void*)intPtr; IL_0353: return (int)(void*)(intPtr + 2); IL_0345: return (int)(void*)(intPtr + 1); IL_0361: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public static int IndexOfAny(ref T searchSpace, T value0, T value1, int length) where T : IEquatable { int num = 0; while (true) { if (length - num >= 8) { T other = Unsafe.Add(ref searchSpace, num); if (!value0.Equals(other) && !value1.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 1); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cb; } other = Unsafe.Add(ref searchSpace, num + 2); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cf; } other = Unsafe.Add(ref searchSpace, num + 3); if (!value0.Equals(other) && !value1.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 4); if (!value0.Equals(other) && !value1.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 5); if (!value0.Equals(other) && !value1.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 6); if (!value0.Equals(other) && !value1.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 7); if (value0.Equals(other) || value1.Equals(other)) { break; } num += 8; continue; } return num + 6; } return num + 5; } return num + 4; } goto IL_02d3; } } else { if (length - num >= 4) { T other = Unsafe.Add(ref searchSpace, num); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c9; } other = Unsafe.Add(ref searchSpace, num + 1); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cb; } other = Unsafe.Add(ref searchSpace, num + 2); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cf; } other = Unsafe.Add(ref searchSpace, num + 3); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02d3; } num += 4; } while (true) { if (num < length) { T other = Unsafe.Add(ref searchSpace, num); if (value0.Equals(other) || value1.Equals(other)) { break; } num++; continue; } return -1; } } goto IL_02c9; IL_02cf: return num + 2; IL_02cb: return num + 1; IL_02d3: return num + 3; IL_02c9: return num; } return num + 7; } public static int IndexOfAny(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable { int num = 0; while (true) { if (length - num >= 8) { T other = Unsafe.Add(ref searchSpace, num); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 1); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03c2; } other = Unsafe.Add(ref searchSpace, num + 2); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03c6; } other = Unsafe.Add(ref searchSpace, num + 3); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 4); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 5); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 6); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 7); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { break; } num += 8; continue; } return num + 6; } return num + 5; } return num + 4; } goto IL_03ca; } } else { if (length - num >= 4) { T other = Unsafe.Add(ref searchSpace, num); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03c0; } other = Unsafe.Add(ref searchSpace, num + 1); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03c2; } other = Unsafe.Add(ref searchSpace, num + 2); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03c6; } other = Unsafe.Add(ref searchSpace, num + 3); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03ca; } num += 4; } while (true) { if (num < length) { T other = Unsafe.Add(ref searchSpace, num); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { break; } num++; continue; } return -1; } } goto IL_03c0; IL_03c0: return num; IL_03c6: return num + 2; IL_03c2: return num + 1; IL_03ca: return num + 3; } return num + 7; } public static int IndexOfAny(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable { 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 LastIndexOf(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable { if (valueLength == 0) { return 0; } T value2 = value; ref T 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 static int LastIndexOf(ref T searchSpace, T value, int length) where T : IEquatable { while (true) { T val; if (length >= 8) { length -= 8; ref T reference = ref value; val = default(T); if (val == null) { val = reference; reference = ref val; } T other = Unsafe.Add(ref searchSpace, length + 7); if (reference.Equals(other)) { break; } ref T reference2 = ref value; val = default(T); if (val == null) { val = reference2; reference2 = ref val; } T other2 = Unsafe.Add(ref searchSpace, length + 6); if (reference2.Equals(other2)) { return length + 6; } ref T reference3 = ref value; val = default(T); if (val == null) { val = reference3; reference3 = ref val; } T other3 = Unsafe.Add(ref searchSpace, length + 5); if (reference3.Equals(other3)) { return length + 5; } ref T reference4 = ref value; val = default(T); if (val == null) { val = reference4; reference4 = ref val; } T other4 = Unsafe.Add(ref searchSpace, length + 4); if (reference4.Equals(other4)) { return length + 4; } ref T reference5 = ref value; val = default(T); if (val == null) { val = reference5; reference5 = ref val; } T other5 = Unsafe.Add(ref searchSpace, length + 3); if (reference5.Equals(other5)) { goto IL_02fd; } ref T reference6 = ref value; val = default(T); if (val == null) { val = reference6; reference6 = ref val; } T other6 = Unsafe.Add(ref searchSpace, length + 2); if (reference6.Equals(other6)) { goto IL_02f9; } ref T reference7 = ref value; val = default(T); if (val == null) { val = reference7; reference7 = ref val; } T other7 = Unsafe.Add(ref searchSpace, length + 1); if (reference7.Equals(other7)) { goto IL_02f5; } ref T reference8 = ref value; val = default(T); if (val == null) { val = reference8; reference8 = ref val; } T other8 = Unsafe.Add(ref searchSpace, length); if (!reference8.Equals(other8)) { continue; } } else { if (length >= 4) { length -= 4; ref T reference9 = ref value; val = default(T); if (val == null) { val = reference9; reference9 = ref val; } T other9 = Unsafe.Add(ref searchSpace, length + 3); if (reference9.Equals(other9)) { goto IL_02fd; } ref T reference10 = ref value; val = default(T); if (val == null) { val = reference10; reference10 = ref val; } T other10 = Unsafe.Add(ref searchSpace, length + 2); if (reference10.Equals(other10)) { goto IL_02f9; } ref T reference11 = ref value; val = default(T); if (val == null) { val = reference11; reference11 = ref val; } T other11 = Unsafe.Add(ref searchSpace, length + 1); if (reference11.Equals(other11)) { goto IL_02f5; } ref T reference12 = ref value; val = default(T); if (val == null) { val = reference12; reference12 = ref val; } T other12 = Unsafe.Add(ref searchSpace, length); if (reference12.Equals(other12)) { goto IL_02f3; } } ref T reference13; T other13; do { if (length > 0) { length--; reference13 = ref value; val = default(T); if (val == null) { val = reference13; reference13 = ref val; } other13 = Unsafe.Add(ref searchSpace, length); continue; } return -1; } while (!reference13.Equals(other13)); } goto IL_02f3; IL_02f5: return length + 1; IL_02f9: return length + 2; IL_02fd: return length + 3; IL_02f3: return length; } return length + 7; } public static int LastIndexOfAny(ref T searchSpace, T value0, T value1, int length) where T : IEquatable { while (true) { if (length >= 8) { length -= 8; T other = Unsafe.Add(ref searchSpace, length + 7); if (value0.Equals(other) || value1.Equals(other)) { break; } other = Unsafe.Add(ref searchSpace, length + 6); if (value0.Equals(other) || value1.Equals(other)) { return length + 6; } other = Unsafe.Add(ref searchSpace, length + 5); if (value0.Equals(other) || value1.Equals(other)) { return length + 5; } other = Unsafe.Add(ref searchSpace, length + 4); if (value0.Equals(other) || value1.Equals(other)) { return length + 4; } other = Unsafe.Add(ref searchSpace, length + 3); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cd; } other = Unsafe.Add(ref searchSpace, length + 2); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c9; } other = Unsafe.Add(ref searchSpace, length + 1); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c5; } other = Unsafe.Add(ref searchSpace, length); if (!value0.Equals(other) && !value1.Equals(other)) { continue; } } else { T other; if (length >= 4) { length -= 4; other = Unsafe.Add(ref searchSpace, length + 3); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02cd; } other = Unsafe.Add(ref searchSpace, length + 2); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c9; } other = Unsafe.Add(ref searchSpace, length + 1); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c5; } other = Unsafe.Add(ref searchSpace, length); if (value0.Equals(other) || value1.Equals(other)) { goto IL_02c3; } } do { if (length > 0) { length--; other = Unsafe.Add(ref searchSpace, length); continue; } return -1; } while (!value0.Equals(other) && !value1.Equals(other)); } goto IL_02c3; IL_02c9: return length + 2; IL_02c5: return length + 1; IL_02c3: return length; IL_02cd: return length + 3; } return length + 7; } public static int LastIndexOfAny(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable { while (true) { if (length >= 8) { length -= 8; T other = Unsafe.Add(ref searchSpace, length + 7); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { break; } other = Unsafe.Add(ref searchSpace, length + 6); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { return length + 6; } other = Unsafe.Add(ref searchSpace, length + 5); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { return length + 5; } other = Unsafe.Add(ref searchSpace, length + 4); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { return length + 4; } other = Unsafe.Add(ref searchSpace, length + 3); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03da; } other = Unsafe.Add(ref searchSpace, length + 2); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03d5; } other = Unsafe.Add(ref searchSpace, length + 1); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03d0; } other = Unsafe.Add(ref searchSpace, length); if (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)) { continue; } } else { T other; if (length >= 4) { length -= 4; other = Unsafe.Add(ref searchSpace, length + 3); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03da; } other = Unsafe.Add(ref searchSpace, length + 2); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03d5; } other = Unsafe.Add(ref searchSpace, length + 1); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03d0; } other = Unsafe.Add(ref searchSpace, length); if (value0.Equals(other) || value1.Equals(other) || value2.Equals(other)) { goto IL_03cd; } } do { if (length > 0) { length--; other = Unsafe.Add(ref searchSpace, length); continue; } return -1; } while (!value0.Equals(other) && !value1.Equals(other) && !value2.Equals(other)); } goto IL_03cd; IL_03d0: return length + 1; IL_03d5: return length + 2; IL_03da: return length + 3; IL_03cd: return length; } return length + 7; } public static int LastIndexOfAny(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable { 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 static bool SequenceEqual(ref T first, ref T second, int length) where T : IEquatable { if (!Unsafe.AreSame(ref first, ref second)) { IntPtr intPtr = (IntPtr)0; while (true) { T val; if (length >= 8) { length -= 8; ref T reference = ref Unsafe.Add(ref first, intPtr); val = default(T); if (val == null) { val = reference; reference = ref val; } T other = Unsafe.Add(ref second, intPtr); if (reference.Equals(other)) { ref T reference2 = ref Unsafe.Add(ref first, intPtr + 1); val = default(T); if (val == null) { val = reference2; reference2 = ref val; } T other2 = Unsafe.Add(ref second, intPtr + 1); if (reference2.Equals(other2)) { ref T reference3 = ref Unsafe.Add(ref first, intPtr + 2); val = default(T); if (val == null) { val = reference3; reference3 = ref val; } T other3 = Unsafe.Add(ref second, intPtr + 2); if (reference3.Equals(other3)) { ref T reference4 = ref Unsafe.Add(ref first, intPtr + 3); val = default(T); if (val == null) { val = reference4; reference4 = ref val; } T other4 = Unsafe.Add(ref second, intPtr + 3); if (reference4.Equals(other4)) { ref T reference5 = ref Unsafe.Add(ref first, intPtr + 4); val = default(T); if (val == null) { val = reference5; reference5 = ref val; } T other5 = Unsafe.Add(ref second, intPtr + 4); if (reference5.Equals(other5)) { ref T reference6 = ref Unsafe.Add(ref first, intPtr + 5); val = default(T); if (val == null) { val = reference6; reference6 = ref val; } T other6 = Unsafe.Add(ref second, intPtr + 5); if (reference6.Equals(other6)) { ref T reference7 = ref Unsafe.Add(ref first, intPtr + 6); val = default(T); if (val == null) { val = reference7; reference7 = ref val; } T other7 = Unsafe.Add(ref second, intPtr + 6); if (reference7.Equals(other7)) { ref T reference8 = ref Unsafe.Add(ref first, intPtr + 7); val = default(T); if (val == null) { val = reference8; reference8 = ref val; } T other8 = Unsafe.Add(ref second, intPtr + 7); if (reference8.Equals(other8)) { intPtr += 8; continue; } } } } } } } } } else { if (length < 4) { goto IL_03c0; } length -= 4; ref T reference9 = ref Unsafe.Add(ref first, intPtr); val = default(T); if (val == null) { val = reference9; reference9 = ref val; } T other9 = Unsafe.Add(ref second, intPtr); if (reference9.Equals(other9)) { ref T reference10 = ref Unsafe.Add(ref first, intPtr + 1); val = default(T); if (val == null) { val = reference10; reference10 = ref val; } T other10 = Unsafe.Add(ref second, intPtr + 1); if (reference10.Equals(other10)) { ref T reference11 = ref Unsafe.Add(ref first, intPtr + 2); val = default(T); if (val == null) { val = reference11; reference11 = ref val; } T other11 = Unsafe.Add(ref second, intPtr + 2); if (reference11.Equals(other11)) { ref T reference12 = ref Unsafe.Add(ref first, intPtr + 3); val = default(T); if (val == null) { val = reference12; reference12 = ref val; } T other12 = Unsafe.Add(ref second, intPtr + 3); if (reference12.Equals(other12)) { intPtr += 4; goto IL_03c0; } } } } } goto IL_03c6; IL_03c0: while (length > 0) { ref T reference13 = ref Unsafe.Add(ref first, intPtr); val = default(T); if (val == null) { val = reference13; reference13 = ref val; } T other13 = Unsafe.Add(ref second, intPtr); if (reference13.Equals(other13)) { intPtr += 1; length--; continue; } goto IL_03c6; } break; IL_03c6: return false; } } return true; } public static int SequenceCompareTo(ref T first, int firstLength, ref T second, int secondLength) where T : IComparable { int num = firstLength; if (num > secondLength) { num = secondLength; } for (int i = 0; i < num; i++) { int num2 = Unsafe.Add(ref first, i).CompareTo(Unsafe.Add(ref second, i)); if (num2 != 0) { return num2; } } return firstLength.CompareTo(secondLength); } } 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(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Format(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_InvalidTypeWithPointersNotSupported, type)); } internal static void ThrowArgumentException_DestinationTooShort() { throw CreateArgumentException_DestinationTooShort(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentException_DestinationTooShort() { return new ArgumentException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>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", <27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Format(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>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", <27c7dfb4-b639-4500-8914-8d6e6caca8cb>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(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.OutstandingReferences); } internal static void ThrowInvalidOperationException_UnexpectedSegmentType() { throw CreateInvalidOperationException_UnexpectedSegmentType(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException_UnexpectedSegmentType() { return new InvalidOperationException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.UnexpectedSegmentType); } internal static void ThrowInvalidOperationException_EndPositionNotReached() { throw CreateInvalidOperationException_EndPositionNotReached(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateInvalidOperationException_EndPositionNotReached() { return new InvalidOperationException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>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(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_BadFormatSpecifier); } internal static void ThrowArgumentException_OverlapAlignmentMismatch() { throw CreateArgumentException_OverlapAlignmentMismatch(); } [MethodImpl(MethodImplOptions.NoInlining)] private static Exception CreateArgumentException_OverlapAlignmentMismatch() { return new ArgumentException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>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(out T value, out int bytesConsumed) { value = default(T); bytesConsumed = 0; ThrowFormatException_BadFormatSpecifier(); return false; } public static void ThrowArgumentValidationException(ReadOnlySequenceSegment startSegment, int startIndex, ReadOnlySequenceSegment endSegment) { throw CreateArgumentValidationException(startSegment, startIndex, endSegment); } private static Exception CreateArgumentValidationException(ReadOnlySequenceSegment startSegment, int startIndex, ReadOnlySequenceSegment 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 <27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.Memory.SR))); internal static string NotSupported_CannotCallEqualsOnSpan => GetResourceString("NotSupported_CannotCallEqualsOnSpan"); internal static string NotSupported_CannotCallGetHashCodeOnSpan => GetResourceString("NotSupported_CannotCallGetHashCodeOnSpan"); internal static string Argument_InvalidTypeWithPointersNotSupported => GetResourceString("Argument_InvalidTypeWithPointersNotSupported"); internal static string Argument_DestinationTooShort => GetResourceString("Argument_DestinationTooShort"); internal static string MemoryDisposed => GetResourceString("MemoryDisposed"); internal static string OutstandingReferences => GetResourceString("OutstandingReferences"); internal static string Argument_BadFormatSpecifier => GetResourceString("Argument_BadFormatSpecifier"); internal static string Argument_GWithPrecisionNotSupported => GetResourceString("Argument_GWithPrecisionNotSupported"); internal static string Argument_CannotParsePrecision => GetResourceString("Argument_CannotParsePrecision"); internal static string Argument_PrecisionTooLarge => GetResourceString("Argument_PrecisionTooLarge"); internal static string Argument_OverlapAlignmentMismatch => GetResourceString("Argument_OverlapAlignmentMismatch"); internal static string EndPositionNotReached => GetResourceString("EndPositionNotReached"); internal static string UnexpectedSegmentType => GetResourceString("UnexpectedSegmentType"); private static bool UsingResourceKeys() { return s_usingResourceKeys; } internal static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } internal static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } 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; } } } namespace System.Numerics.Hashing { internal static class <27c7dfb4-b639-4500-8914-8d6e6caca8cb>HashHelpers { public static readonly int RandomSeed = Guid.NewGuid().GetHashCode(); public static int Combine(int h1, int h2) { uint num = (uint)((h1 << 5) | (h1 >>> 27)); return ((int)num + h1) ^ h2; } } } namespace System.Runtime.InteropServices { internal static class MemoryMarshal { public static bool TryGetArray(ReadOnlyMemory memory, out ArraySegment segment) { int start; int length; object objectStartLength = memory.GetObjectStartLength(out start, out length); if (start < 0) { if (((MemoryManager)objectStartLength).TryGetArray(out var segment2)) { segment = new ArraySegment(segment2.Array, segment2.Offset + (start & 0x7FFFFFFF), length); return true; } } else if (objectStartLength is T[] array) { segment = new ArraySegment(array, start, length & 0x7FFFFFFF); return true; } if ((length & 0x7FFFFFFF) == 0) { segment = new ArraySegment(System.SpanHelpers.PerTypeValues.EmptyArray); return true; } segment = default(ArraySegment); return false; } public static bool TryGetMemoryManager(ReadOnlyMemory memory, out TManager manager) where TManager : MemoryManager { int start; int length; TManager val = (manager = memory.GetObjectStartLength(out start, out length) as TManager); return manager != null; } public static bool TryGetMemoryManager(ReadOnlyMemory memory, out TManager manager, out int start, out int length) where TManager : MemoryManager { TManager val = (manager = memory.GetObjectStartLength(out start, out length) as TManager); start &= int.MaxValue; if (manager == null) { start = 0; length = 0; return false; } return true; } public static IEnumerable ToEnumerable(ReadOnlyMemory memory) { for (int i = 0; i < memory.Length; i++) { yield return memory.Span[i]; } } public static bool TryGetString(ReadOnlyMemory memory, out string text, out int start, out int length) { if (memory.GetObjectStartLength(out var start2, out var length2) is string text2) { text = text2; start = start2; length = length2; return true; } text = null; start = 0; length = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Read(ReadOnlySpan source) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if (Unsafe.SizeOf() > source.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } return Unsafe.ReadUnaligned(ref GetReference(source)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryRead(ReadOnlySpan source, out T value) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if (Unsafe.SizeOf() > (uint)source.Length) { value = default(T); return false; } value = Unsafe.ReadUnaligned(ref GetReference(source)); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Write(Span destination, ref T value) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if ((uint)Unsafe.SizeOf() > (uint)destination.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } Unsafe.WriteUnaligned(ref GetReference(destination), value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWrite(Span destination, ref T value) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } if (Unsafe.SizeOf() > (uint)destination.Length) { return false; } Unsafe.WriteUnaligned(ref GetReference(destination), value); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory CreateFromPinnedArray(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(); } return default(Memory); } 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(); } return new Memory((object)array, start, length | int.MinValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span AsBytes(Span span) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } int length = checked(span.Length * Unsafe.SizeOf()); return new Span(Unsafe.As>(span.Pinnable), span.ByteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan AsBytes(ReadOnlySpan span) where T : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); } int length = checked(span.Length * Unsafe.SizeOf()); return new ReadOnlySpan(Unsafe.As>(span.Pinnable), span.ByteOffset, length); } public static Memory AsMemory(ReadOnlyMemory memory) { return Unsafe.As, Memory>(ref memory); } public unsafe static ref T GetReference(Span span) { if (span.Pinnable == null) { return ref Unsafe.AsRef(span.ByteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref span.Pinnable.Data, span.ByteOffset); } public unsafe static ref T GetReference(ReadOnlySpan span) { if (span.Pinnable == null) { return ref Unsafe.AsRef(span.ByteOffset.ToPointer()); } return ref Unsafe.AddByteOffset(ref span.Pinnable.Data, span.ByteOffset); } public static Span Cast(Span span) where TFrom : struct where TTo : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TFrom)); } if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TTo)); } checked { int length = (int)unchecked(checked(unchecked((long)span.Length) * unchecked((long)Unsafe.SizeOf())) / Unsafe.SizeOf()); return new Span(Unsafe.As>(span.Pinnable), span.ByteOffset, length); } } public static ReadOnlySpan Cast(ReadOnlySpan span) where TFrom : struct where TTo : struct { if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TFrom)); } if (System.SpanHelpers.IsReferenceOrContainsReferences()) { System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TTo)); } checked { int length = (int)unchecked(checked(unchecked((long)span.Length) * unchecked((long)Unsafe.SizeOf())) / Unsafe.SizeOf()); return new ReadOnlySpan(Unsafe.As>(span.Pinnable), span.ByteOffset, length); } } } internal static class SequenceMarshal { public static bool TryGetReadOnlySequenceSegment(ReadOnlySequence sequence, out ReadOnlySequenceSegment startSegment, out int startIndex, out ReadOnlySequenceSegment endSegment, out int endIndex) { return sequence.TryGetReadOnlySequenceSegment(out startSegment, out startIndex, out endSegment, out endIndex); } public static bool TryGetArray(ReadOnlySequence sequence, out ArraySegment segment) { return sequence.TryGetArray(out segment); } public static bool TryGetReadOnlyMemory(ReadOnlySequence sequence, out ReadOnlyMemory memory) { if (!sequence.IsSingleSegment) { memory = default(ReadOnlyMemory); return false; } memory = sequence.First; return true; } internal static bool TryGetString(ReadOnlySequence sequence, out string text, out int start, out int length) { return sequence.TryGetString(out text, out start, out length); } } } namespace System.Buffers { internal sealed class ArrayMemoryPool : MemoryPool { private sealed class ArrayMemoryPoolBuffer : IMemoryOwner, IDisposable { private T[] _array; public Memory Memory { get { T[] array = _array; if (array == null) { System.ThrowHelper.ThrowObjectDisposedException_ArrayMemoryPoolBuffer(); } return new Memory(array); } } public ArrayMemoryPoolBuffer(int size) { _array = ArrayPool.Shared.Rent(size); } public void Dispose() { T[] array = _array; if (array != null) { _array = null; ArrayPool.Shared.Return(array); } } } private const int s_maxBufferSize = int.MaxValue; public sealed override int MaxBufferSize => int.MaxValue; public sealed override IMemoryOwner Rent(int minimumBufferSize = -1) { if (minimumBufferSize == -1) { minimumBufferSize = 1 + 4095 / Unsafe.SizeOf(); } else if ((uint)minimumBufferSize > 2147483647u) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.minimumBufferSize); } return new ArrayMemoryPoolBuffer(minimumBufferSize); } protected sealed override void Dispose(bool disposing) { } } internal static class BuffersExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SequencePosition? PositionOf(this in ReadOnlySequence source, T value) where T : IEquatable { if (source.IsSingleSegment) { int num = source.First.Span.IndexOf(value); if (num != -1) { return source.GetPosition(num); } return null; } return PositionOfMultiSegment(in source, value); } private static SequencePosition? PositionOfMultiSegment(in ReadOnlySequence source, T value) where T : IEquatable { SequencePosition position = source.Start; SequencePosition origin = position; ReadOnlyMemory memory; while (source.TryGet(ref position, out memory)) { int num = memory.Span.IndexOf(value); if (num != -1) { return source.GetPosition(num, origin); } if (position.GetObject() == null) { break; } origin = position; } return null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void CopyTo(this in ReadOnlySequence source, Span destination) { if (source.Length > destination.Length) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.destination); } if (source.IsSingleSegment) { source.First.Span.CopyTo(destination); } else { CopyToMultiSegment(in source, destination); } } private static void CopyToMultiSegment(in ReadOnlySequence sequence, Span destination) { SequencePosition position = sequence.Start; ReadOnlyMemory memory; while (sequence.TryGet(ref position, out memory)) { ReadOnlySpan span = memory.Span; span.CopyTo(destination); if (position.GetObject() != null) { destination = destination.Slice(span.Length); continue; } break; } } public static T[] ToArray(this in ReadOnlySequence sequence) { T[] array = new T[sequence.Length]; CopyTo(in sequence, array); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Write(this IBufferWriter writer, ReadOnlySpan value) { Span span = writer.GetSpan(); if (value.Length <= span.Length) { value.CopyTo(span); writer.Advance(value.Length); } else { WriteMultiSegment(writer, in value, span); } } private static void WriteMultiSegment(IBufferWriter writer, in ReadOnlySpan source, Span destination) { ReadOnlySpan readOnlySpan = source; while (true) { int num = Math.Min(destination.Length, readOnlySpan.Length); readOnlySpan.Slice(0, num).CopyTo(destination); writer.Advance(num); readOnlySpan = readOnlySpan.Slice(num); if (readOnlySpan.Length > 0) { destination = writer.GetSpan(readOnlySpan.Length); continue; } break; } } } internal interface IBufferWriter { void Advance(int count); Memory GetMemory(int sizeHint = 0); Span GetSpan(int sizeHint = 0); } internal interface IMemoryOwner : IDisposable { Memory Memory { get; } } internal interface IPinnable { MemoryHandle Pin(int elementIndex); void Unpin(); } internal struct MemoryHandle : IDisposable { private unsafe void* _pointer; private GCHandle _handle; private IPinnable _pinnable; [CLSCompliant(false)] public unsafe void* Pointer => _pointer; [CLSCompliant(false)] public unsafe MemoryHandle(void* pointer, GCHandle handle = default(GCHandle), IPinnable pinnable = null) { _pointer = pointer; _handle = handle; _pinnable = pinnable; } public unsafe void Dispose() { if (_handle.IsAllocated) { _handle.Free(); } if (_pinnable != null) { _pinnable.Unpin(); _pinnable = null; } _pointer = null; } } internal abstract class MemoryManager : IMemoryOwner, IDisposable, IPinnable { public virtual Memory Memory => new Memory(this, GetSpan().Length); public abstract Span GetSpan(); public abstract MemoryHandle Pin(int elementIndex = 0); public abstract void Unpin(); [MethodImpl(MethodImplOptions.AggressiveInlining)] protected Memory CreateMemory(int length) { return new Memory(this, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected Memory CreateMemory(int start, int length) { return new Memory(this, start, length); } protected internal virtual bool TryGetArray(out ArraySegment segment) { segment = default(ArraySegment); return false; } void IDisposable.Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected abstract void Dispose(bool disposing); } internal abstract class MemoryPool : IDisposable { private static readonly MemoryPool s_shared = new System.Buffers.ArrayMemoryPool(); public static MemoryPool Shared => s_shared; public abstract int MaxBufferSize { get; } public abstract IMemoryOwner Rent(int minBufferSize = -1); public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected abstract void Dispose(bool disposing); } internal enum OperationStatus { Done, DestinationTooSmall, NeedMoreData, InvalidData } [DebuggerTypeProxy(typeof(System.Buffers.ReadOnlySequenceDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] internal readonly struct ReadOnlySequence { public struct Enumerator { private readonly ReadOnlySequence _sequence; private SequencePosition _next; private ReadOnlyMemory _currentMemory; public ReadOnlyMemory Current => _currentMemory; public Enumerator(in ReadOnlySequence sequence) { _currentMemory = default(ReadOnlyMemory); _next = sequence.Start; _sequence = sequence; } public bool MoveNext() { if (_next.GetObject() == null) { return false; } return _sequence.TryGet(ref _next, out _currentMemory); } } private enum SequenceType { MultiSegment, Array, MemoryManager, String, Empty } private readonly SequencePosition _sequenceStart; private readonly SequencePosition _sequenceEnd; public static readonly ReadOnlySequence Empty = new ReadOnlySequence(System.SpanHelpers.PerTypeValues.EmptyArray); public long Length => GetLength(); public bool IsEmpty => Length == 0; public bool IsSingleSegment { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _sequenceStart.GetObject() == _sequenceEnd.GetObject(); } } public ReadOnlyMemory First => GetFirstBuffer(); public SequencePosition Start => _sequenceStart; public SequencePosition End => _sequenceEnd; [MethodImpl(MethodImplOptions.AggressiveInlining)] private ReadOnlySequence(object startSegment, int startIndexAndFlags, object endSegment, int endIndexAndFlags) { _sequenceStart = new SequencePosition(startSegment, startIndexAndFlags); _sequenceEnd = new SequencePosition(endSegment, endIndexAndFlags); } public ReadOnlySequence(ReadOnlySequenceSegment startSegment, int startIndex, ReadOnlySequenceSegment endSegment, int endIndex) { if (startSegment == null || endSegment == null || (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex) || (uint)startSegment.Memory.Length < (uint)startIndex || (uint)endSegment.Memory.Length < (uint)endIndex || (startSegment == endSegment && endIndex < startIndex)) { System.ThrowHelper.ThrowArgumentValidationException(startSegment, startIndex, endSegment); } _sequenceStart = new SequencePosition(startSegment, System.Buffers.ReadOnlySequence.SegmentToSequenceStart(startIndex)); _sequenceEnd = new SequencePosition(endSegment, System.Buffers.ReadOnlySequence.SegmentToSequenceEnd(endIndex)); } public ReadOnlySequence(T[] array) { if (array == null) { System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.array); } _sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(0)); _sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(array.Length)); } public ReadOnlySequence(T[] array, int start, int length) { if (array == null || (uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) { System.ThrowHelper.ThrowArgumentValidationException(array, start); } _sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(start)); _sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(start + length)); } public ReadOnlySequence(ReadOnlyMemory memory) { ArraySegment segment; if (MemoryMarshal.TryGetMemoryManager>(memory, out var manager, out var start, out var length)) { _sequenceStart = new SequencePosition(manager, System.Buffers.ReadOnlySequence.MemoryManagerToSequenceStart(start)); _sequenceEnd = new SequencePosition(manager, System.Buffers.ReadOnlySequence.MemoryManagerToSequenceEnd(start + length)); } else if (MemoryMarshal.TryGetArray(memory, out segment)) { T[] array = segment.Array; int offset = segment.Offset; _sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(offset)); _sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(offset + segment.Count)); } else if (typeof(T) == typeof(char)) { if (!MemoryMarshal.TryGetString((ReadOnlyMemory)(object)memory, out var text, out var start2, out length)) { System.ThrowHelper.ThrowInvalidOperationException(); } _sequenceStart = new SequencePosition(text, System.Buffers.ReadOnlySequence.StringToSequenceStart(start2)); _sequenceEnd = new SequencePosition(text, System.Buffers.ReadOnlySequence.StringToSequenceEnd(start2 + length)); } else { System.ThrowHelper.ThrowInvalidOperationException(); _sequenceStart = default(SequencePosition); _sequenceEnd = default(SequencePosition); } } public ReadOnlySequence Slice(long start, long length) { if (start < 0 || length < 0) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start); } int index = GetIndex(in _sequenceStart); int index2 = GetIndex(in _sequenceEnd); object obj = _sequenceStart.GetObject(); object obj2 = _sequenceEnd.GetObject(); SequencePosition position; SequencePosition end; if (obj != obj2) { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj; int num = readOnlySequenceSegment.Memory.Length - index; if (num > start) { index += (int)start; position = new SequencePosition(obj, index); end = GetEndPosition(readOnlySequenceSegment, obj, index, obj2, index2, length); } else { if (num < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } position = SeekMultiSegment(readOnlySequenceSegment.Next, obj2, index2, start - num, System.ExceptionArgument.start); int index3 = GetIndex(in position); object obj3 = position.GetObject(); if (obj3 != obj2) { end = GetEndPosition((ReadOnlySequenceSegment)obj3, obj3, index3, obj2, index2, length); } else { if (index2 - index3 < length) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L); } end = new SequencePosition(obj3, index3 + (int)length); } } } else { if (index2 - index < start) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(-1L); } index += (int)start; position = new SequencePosition(obj, index); if (index2 - index < length) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L); } end = new SequencePosition(obj, index + (int)length); } return SliceImpl(in position, in end); } public ReadOnlySequence Slice(long start, SequencePosition end) { if (start < 0) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start); } uint index = (uint)GetIndex(in end); object obj = end.GetObject(); uint index2 = (uint)GetIndex(in _sequenceStart); object obj2 = _sequenceStart.GetObject(); uint index3 = (uint)GetIndex(in _sequenceEnd); object obj3 = _sequenceEnd.GetObject(); if (obj2 == obj3) { if (!InRange(index, index2, index3)) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } if (index - index2 < start) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(-1L); } } else { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj2; ulong num = (ulong)(readOnlySequenceSegment.RunningIndex + index2); ulong num2 = (ulong)(((ReadOnlySequenceSegment)obj).RunningIndex + index); if (!InRange(num2, num, (ulong)(((ReadOnlySequenceSegment)obj3).RunningIndex + index3))) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } if ((ulong)((long)num + start) > num2) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); } int num3 = readOnlySequenceSegment.Memory.Length - (int)index2; if (num3 <= start) { if (num3 < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return SliceImpl(SeekMultiSegment(readOnlySequenceSegment.Next, obj, (int)index, start - num3, System.ExceptionArgument.start), in end); } } return SliceImpl(new SequencePosition(obj2, (int)index2 + (int)start), in end); } public ReadOnlySequence Slice(SequencePosition start, long length) { uint index = (uint)GetIndex(in start); object obj = start.GetObject(); uint index2 = (uint)GetIndex(in _sequenceStart); object obj2 = _sequenceStart.GetObject(); uint index3 = (uint)GetIndex(in _sequenceEnd); object obj3 = _sequenceEnd.GetObject(); if (obj2 == obj3) { if (!InRange(index, index2, index3)) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } if (length < 0) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L); } if (index3 - index < length) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L); } } else { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj; ulong num = (ulong)(readOnlySequenceSegment.RunningIndex + index); ulong start2 = (ulong)(((ReadOnlySequenceSegment)obj2).RunningIndex + index2); ulong num2 = (ulong)(((ReadOnlySequenceSegment)obj3).RunningIndex + index3); if (!InRange(num, start2, num2)) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } if (length < 0) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L); } if ((ulong)((long)num + length) > num2) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } int num3 = readOnlySequenceSegment.Memory.Length - (int)index; if (num3 < length) { if (num3 < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return SliceImpl(in start, SeekMultiSegment(readOnlySequenceSegment.Next, obj3, (int)index3, length - num3, System.ExceptionArgument.length)); } } return SliceImpl(in start, new SequencePosition(obj, (int)index + (int)length)); } public ReadOnlySequence Slice(int start, int length) { return Slice((long)start, (long)length); } public ReadOnlySequence Slice(int start, SequencePosition end) { return Slice((long)start, end); } public ReadOnlySequence Slice(SequencePosition start, int length) { return Slice(start, (long)length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySequence Slice(SequencePosition start, SequencePosition end) { BoundsCheck((uint)GetIndex(in start), start.GetObject(), (uint)GetIndex(in end), end.GetObject()); return SliceImpl(in start, in end); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySequence Slice(SequencePosition start) { BoundsCheck(in start); return SliceImpl(in start, in _sequenceEnd); } public ReadOnlySequence Slice(long start) { if (start < 0) { System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start); } if (start == 0L) { return this; } return SliceImpl(Seek(in _sequenceStart, in _sequenceEnd, start, System.ExceptionArgument.start), in _sequenceEnd); } public override string ToString() { if (typeof(T) == typeof(char)) { ReadOnlySequence source = this; ReadOnlySequence sequence = Unsafe.As, ReadOnlySequence>(ref source); if (SequenceMarshal.TryGetString(sequence, out var text, out var start, out var length)) { return text.Substring(start, length); } if (Length < int.MaxValue) { return new string(BuffersExtensions.ToArray(in sequence)); } } return $"System.Buffers.ReadOnlySequence<{typeof(T).Name}>[{Length}]"; } public Enumerator GetEnumerator() { return new Enumerator(in this); } public SequencePosition GetPosition(long offset) { return GetPosition(offset, _sequenceStart); } public SequencePosition GetPosition(long offset, SequencePosition origin) { if (offset < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_OffsetOutOfRange(); } return Seek(in origin, in _sequenceEnd, offset, System.ExceptionArgument.offset); } public bool TryGet(ref SequencePosition position, out ReadOnlyMemory memory, bool advance = true) { SequencePosition next; bool result = TryGetBuffer(in position, out memory, out next); if (advance) { position = next; } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal bool TryGetBuffer(in SequencePosition position, out ReadOnlyMemory memory, out SequencePosition next) { object obj = position.GetObject(); next = default(SequencePosition); if (obj == null) { memory = default(ReadOnlyMemory); return false; } SequenceType sequenceType = GetSequenceType(); object obj2 = _sequenceEnd.GetObject(); int index = GetIndex(in position); int index2 = GetIndex(in _sequenceEnd); if (sequenceType == SequenceType.MultiSegment) { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj; if (readOnlySequenceSegment != obj2) { ReadOnlySequenceSegment next2 = readOnlySequenceSegment.Next; if (next2 == null) { System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } next = new SequencePosition(next2, 0); memory = readOnlySequenceSegment.Memory.Slice(index); } else { memory = readOnlySequenceSegment.Memory.Slice(index, index2 - index); } } else { if (obj != obj2) { System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } if (sequenceType == SequenceType.Array) { memory = new ReadOnlyMemory((T[])obj, index, index2 - index); } else if (typeof(T) == typeof(char) && sequenceType == SequenceType.String) { memory = (ReadOnlyMemory)(object)MemoryExtensions.AsMemory((string)obj, index, index2 - index); } else { memory = ((MemoryManager)obj).Memory.Slice(index, index2 - index); } } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ReadOnlyMemory GetFirstBuffer() { object obj = _sequenceStart.GetObject(); if (obj == null) { return default(ReadOnlyMemory); } int integer = _sequenceStart.GetInteger(); int integer2 = _sequenceEnd.GetInteger(); bool flag = obj != _sequenceEnd.GetObject(); if (integer >= 0) { if (integer2 >= 0) { ReadOnlyMemory memory = ((ReadOnlySequenceSegment)obj).Memory; if (flag) { return memory.Slice(integer); } return memory.Slice(integer, integer2 - integer); } if (flag) { System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } return new ReadOnlyMemory((T[])obj, integer, (integer2 & 0x7FFFFFFF) - integer); } if (flag) { System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached(); } if (typeof(T) == typeof(char) && integer2 < 0) { return (ReadOnlyMemory)(object)MemoryExtensions.AsMemory((string)obj, integer & 0x7FFFFFFF, integer2 - integer); } integer &= 0x7FFFFFFF; return ((MemoryManager)obj).Memory.Slice(integer, integer2 - integer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private SequencePosition Seek(in SequencePosition start, in SequencePosition end, long offset, System.ExceptionArgument argument) { int index = GetIndex(in start); int index2 = GetIndex(in end); object obj = start.GetObject(); object obj2 = end.GetObject(); if (obj != obj2) { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj; int num = readOnlySequenceSegment.Memory.Length - index; if (num <= offset) { if (num < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return SeekMultiSegment(readOnlySequenceSegment.Next, obj2, index2, offset - num, argument); } } else if (index2 - index < offset) { System.ThrowHelper.ThrowArgumentOutOfRangeException(argument); } return new SequencePosition(obj, index + (int)offset); } [MethodImpl(MethodImplOptions.NoInlining)] private static SequencePosition SeekMultiSegment(ReadOnlySequenceSegment currentSegment, object endObject, int endIndex, long offset, System.ExceptionArgument argument) { while (true) { if (currentSegment != null && currentSegment != endObject) { int length = currentSegment.Memory.Length; if (length > offset) { break; } offset -= length; currentSegment = currentSegment.Next; continue; } if (currentSegment == null || endIndex < offset) { System.ThrowHelper.ThrowArgumentOutOfRangeException(argument); } break; } return new SequencePosition(currentSegment, (int)offset); } private void BoundsCheck(in SequencePosition position) { uint index = (uint)GetIndex(in position); uint index2 = (uint)GetIndex(in _sequenceStart); uint index3 = (uint)GetIndex(in _sequenceEnd); object obj = _sequenceStart.GetObject(); object obj2 = _sequenceEnd.GetObject(); if (obj == obj2) { if (!InRange(index, index2, index3)) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return; } ulong start = (ulong)(((ReadOnlySequenceSegment)obj).RunningIndex + index2); if (!InRange((ulong)(((ReadOnlySequenceSegment)position.GetObject()).RunningIndex + index), start, (ulong)(((ReadOnlySequenceSegment)obj2).RunningIndex + index3))) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } } private void BoundsCheck(uint sliceStartIndex, object sliceStartObject, uint sliceEndIndex, object sliceEndObject) { uint index = (uint)GetIndex(in _sequenceStart); uint index2 = (uint)GetIndex(in _sequenceEnd); object obj = _sequenceStart.GetObject(); object obj2 = _sequenceEnd.GetObject(); if (obj == obj2) { if (sliceStartObject != sliceEndObject || sliceStartObject != obj || sliceStartIndex > sliceEndIndex || sliceStartIndex < index || sliceEndIndex > index2) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return; } ulong num = (ulong)(((ReadOnlySequenceSegment)sliceStartObject).RunningIndex + sliceStartIndex); ulong num2 = (ulong)(((ReadOnlySequenceSegment)sliceEndObject).RunningIndex + sliceEndIndex); if (num > num2) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } if (num < (ulong)(((ReadOnlySequenceSegment)obj).RunningIndex + index) || num2 > (ulong)(((ReadOnlySequenceSegment)obj2).RunningIndex + index2)) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } } private static SequencePosition GetEndPosition(ReadOnlySequenceSegment startSegment, object startObject, int startIndex, object endObject, int endIndex, long length) { int num = startSegment.Memory.Length - startIndex; if (num > length) { return new SequencePosition(startObject, startIndex + (int)length); } if (num < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange(); } return SeekMultiSegment(startSegment.Next, endObject, endIndex, length - num, System.ExceptionArgument.length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private SequenceType GetSequenceType() { return (SequenceType)(-(2 * (_sequenceStart.GetInteger() >> 31) + (_sequenceEnd.GetInteger() >> 31))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int GetIndex(in SequencePosition position) { return position.GetInteger() & 0x7FFFFFFF; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ReadOnlySequence SliceImpl(in SequencePosition start, in SequencePosition end) { return new ReadOnlySequence(start.GetObject(), GetIndex(in start) | (_sequenceStart.GetInteger() & int.MinValue), end.GetObject(), GetIndex(in end) | (_sequenceEnd.GetInteger() & int.MinValue)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private long GetLength() { int index = GetIndex(in _sequenceStart); int index2 = GetIndex(in _sequenceEnd); object obj = _sequenceStart.GetObject(); object obj2 = _sequenceEnd.GetObject(); if (obj != obj2) { ReadOnlySequenceSegment readOnlySequenceSegment = (ReadOnlySequenceSegment)obj; ReadOnlySequenceSegment readOnlySequenceSegment2 = (ReadOnlySequenceSegment)obj2; return readOnlySequenceSegment2.RunningIndex + index2 - (readOnlySequenceSegment.RunningIndex + index); } return index2 - index; } internal bool TryGetReadOnlySequenceSegment(out ReadOnlySequenceSegment startSegment, out int startIndex, out ReadOnlySequenceSegment endSegment, out int endIndex) { object obj = _sequenceStart.GetObject(); if (obj == null || GetSequenceType() != SequenceType.MultiSegment) { startSegment = null; startIndex = 0; endSegment = null; endIndex = 0; return false; } startSegment = (ReadOnlySequenceSegment)obj; startIndex = GetIndex(in _sequenceStart); endSegment = (ReadOnlySequenceSegment)_sequenceEnd.GetObject(); endIndex = GetIndex(in _sequenceEnd); return true; } internal bool TryGetArray(out ArraySegment segment) { if (GetSequenceType() != SequenceType.Array) { segment = default(ArraySegment); return false; } int index = GetIndex(in _sequenceStart); segment = new ArraySegment((T[])_sequenceStart.GetObject(), index, GetIndex(in _sequenceEnd) - index); return true; } internal bool TryGetString(out string text, out int start, out int length) { if (typeof(T) != typeof(char) || GetSequenceType() != SequenceType.String) { start = 0; length = 0; text = null; return false; } start = GetIndex(in _sequenceStart); length = GetIndex(in _sequenceEnd) - start; text = (string)_sequenceStart.GetObject(); return true; } private static bool InRange(uint value, uint start, uint end) { return value - start <= end - start; } private static bool InRange(ulong value, ulong start, ulong end) { return value - start <= end - start; } } internal static class ReadOnlySequence { public const int FlagBitMask = int.MinValue; public const int IndexBitMask = int.MaxValue; public const int SegmentStartMask = 0; public const int SegmentEndMask = 0; public const int ArrayStartMask = 0; public const int ArrayEndMask = int.MinValue; public const int MemoryManagerStartMask = int.MinValue; public const int MemoryManagerEndMask = 0; public const int StringStartMask = int.MinValue; public const int StringEndMask = int.MinValue; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SegmentToSequenceStart(int startIndex) { return startIndex | 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SegmentToSequenceEnd(int endIndex) { return endIndex | 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ArrayToSequenceStart(int startIndex) { return startIndex | 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ArrayToSequenceEnd(int endIndex) { return endIndex | int.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int MemoryManagerToSequenceStart(int startIndex) { return startIndex | int.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int MemoryManagerToSequenceEnd(int endIndex) { return endIndex | 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int StringToSequenceStart(int startIndex) { return startIndex | int.MinValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int StringToSequenceEnd(int endIndex) { return endIndex | int.MinValue; } } internal sealed class ReadOnlySequenceDebugView { [DebuggerDisplay("Count: {Segments.Length}", Name = "Segments")] public struct ReadOnlySequenceDebugViewSegments { [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public ReadOnlyMemory[] Segments { get; set; } } private readonly T[] _array; private readonly ReadOnlySequenceDebugViewSegments _segments; public ReadOnlySequenceDebugViewSegments BufferSegments => _segments; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public T[] Items => _array; public ReadOnlySequenceDebugView(ReadOnlySequence sequence) { _array = BuffersExtensions.ToArray(in sequence); int num = 0; ReadOnlySequence.Enumerator enumerator = sequence.GetEnumerator(); while (enumerator.MoveNext()) { ReadOnlyMemory current = enumerator.Current; num++; } ReadOnlyMemory[] array = new ReadOnlyMemory[num]; int num2 = 0; ReadOnlySequence.Enumerator enumerator2 = sequence.GetEnumerator(); while (enumerator2.MoveNext()) { ReadOnlyMemory current2 = enumerator2.Current; array[num2] = current2; num2++; } _segments = new ReadOnlySequenceDebugViewSegments { Segments = array }; } } internal abstract class ReadOnlySequenceSegment { public ReadOnlyMemory Memory { get; protected set; } public ReadOnlySequenceSegment Next { get; protected set; } public long RunningIndex { get; protected set; } } internal readonly struct StandardFormat : IEquatable { public const byte NoPrecision = byte.MaxValue; public const byte MaxPrecision = 99; private readonly byte _format; private readonly byte _precision; public char Symbol => (char)_format; public byte Precision => _precision; public bool HasPrecision => _precision != byte.MaxValue; public bool IsDefault { get { if (_format == 0) { return _precision == 0; } return false; } } public StandardFormat(char symbol, byte precision = byte.MaxValue) { if (precision != byte.MaxValue && precision > 99) { System.ThrowHelper.ThrowArgumentOutOfRangeException_PrecisionTooLarge(); } if (symbol != (byte)symbol) { System.ThrowHelper.ThrowArgumentOutOfRangeException_SymbolDoesNotFit(); } _format = (byte)symbol; _precision = precision; } public static implicit operator StandardFormat(char symbol) { return new StandardFormat(symbol); } public static StandardFormat Parse(ReadOnlySpan format) { if (format.Length == 0) { return default(StandardFormat); } char symbol = format[0]; byte precision; if (format.Length == 1) { precision = byte.MaxValue; } else { uint num = 0u; for (int i = 1; i < format.Length; i++) { uint num2 = (uint)(format[i] - 48); if (num2 > 9) { throw new FormatException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Format(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_CannotParsePrecision, (byte)99)); } num = num * 10 + num2; if (num > 99) { throw new FormatException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Format(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_PrecisionTooLarge, (byte)99)); } } precision = (byte)num; } return new StandardFormat(symbol, precision); } public static StandardFormat Parse(string format) { if (format != null) { return Parse(MemoryExtensions.AsSpan(format)); } return default(StandardFormat); } public override bool Equals(object obj) { if (obj is StandardFormat other) { return Equals(other); } return false; } public override int GetHashCode() { byte format = _format; int hashCode = format.GetHashCode(); format = _precision; return hashCode ^ format.GetHashCode(); } public bool Equals(StandardFormat other) { if (_format == other._format) { return _precision == other._precision; } return false; } public unsafe override string ToString() { char* ptr = stackalloc char[4]; int length = 0; char symbol = Symbol; if (symbol != 0) { ptr[length++] = symbol; byte b = Precision; if (b != byte.MaxValue) { if (b >= 100) { ptr[length++] = (char)(48 + b / 100 % 10); b %= 100; } if (b >= 10) { ptr[length++] = (char)(48 + b / 10 % 10); b %= 10; } ptr[length++] = (char)(48 + b); } } return new string(ptr, 0, length); } public static bool operator ==(StandardFormat left, StandardFormat right) { return left.Equals(right); } public static bool operator !=(StandardFormat left, StandardFormat right) { return !left.Equals(right); } } } namespace System.Buffers.Text { internal static class Base64 { private static readonly sbyte[] s_decodingMap = new sbyte[256] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; private static readonly byte[] s_encodingMap = new byte[64] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 }; private const byte EncodingPad = 61; private const int MaximumEncodeLength = 1610612733; public static OperationStatus DecodeFromUtf8(ReadOnlySpan utf8, Span bytes, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) { ref byte reference = ref MemoryMarshal.GetReference(utf8); ref byte reference2 = ref MemoryMarshal.GetReference(bytes); int num = utf8.Length & -4; int length = bytes.Length; int num2 = 0; int num3 = 0; if (utf8.Length != 0) { ref sbyte reference3 = ref s_decodingMap[0]; int num4 = (isFinalBlock ? 4 : 0); int num5 = 0; num5 = ((length < GetMaxDecodedFromUtf8Length(num)) ? (length / 3 * 4) : (num - num4)); while (true) { if (num2 < num5) { int num6 = Decode(ref Unsafe.Add(ref reference, num2), ref reference3); if (num6 >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), num6); num3 += 3; num2 += 4; continue; } } else { if (num5 != num - num4) { goto IL_0205; } if (num2 == num) { if (!isFinalBlock) { bytesConsumed = num2; bytesWritten = num3; return OperationStatus.NeedMoreData; } } else { int elementOffset = Unsafe.Add(ref reference, num - 4); int elementOffset2 = Unsafe.Add(ref reference, num - 3); int num7 = Unsafe.Add(ref reference, num - 2); int num8 = Unsafe.Add(ref reference, num - 1); elementOffset = Unsafe.Add(ref reference3, elementOffset); elementOffset2 = Unsafe.Add(ref reference3, elementOffset2); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset |= elementOffset2; if (num8 != 61) { num7 = Unsafe.Add(ref reference3, num7); num8 = Unsafe.Add(ref reference3, num8); num7 <<= 6; elementOffset |= num8; elementOffset |= num7; if (elementOffset >= 0) { if (num3 <= length - 3) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), elementOffset); num3 += 3; goto IL_01eb; } goto IL_0205; } } else if (num7 != 61) { num7 = Unsafe.Add(ref reference3, num7); num7 <<= 6; elementOffset |= num7; if (elementOffset >= 0) { if (num3 <= length - 2) { Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16); Unsafe.Add(ref reference2, num3 + 1) = (byte)(elementOffset >> 8); num3 += 2; goto IL_01eb; } goto IL_0205; } } else if (elementOffset >= 0) { if (num3 <= length - 1) { Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16); num3++; goto IL_01eb; } goto IL_0205; } } } goto IL_022b; IL_01eb: num2 += 4; if (num == utf8.Length) { break; } goto IL_022b; IL_022b: bytesConsumed = num2; bytesWritten = num3; return OperationStatus.InvalidData; IL_0205: if (!(num != utf8.Length && isFinalBlock)) { bytesConsumed = num2; bytesWritten = num3; return OperationStatus.DestinationTooSmall; } goto IL_022b; } } bytesConsumed = num2; bytesWritten = num3; return OperationStatus.Done; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMaxDecodedFromUtf8Length(int length) { if (length < 0) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } return (length >> 2) * 3; } public static OperationStatus DecodeFromUtf8InPlace(Span buffer, out int bytesWritten) { int length = buffer.Length; int num = 0; int num2 = 0; if (length == (length >> 2) * 4) { if (length == 0) { goto IL_016d; } ref byte reference = ref MemoryMarshal.GetReference(buffer); ref sbyte reference2 = ref s_decodingMap[0]; while (num < length - 4) { int num3 = Decode(ref Unsafe.Add(ref reference, num), ref reference2); if (num3 >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), num3); num2 += 3; num += 4; continue; } goto IL_0172; } int elementOffset = Unsafe.Add(ref reference, length - 4); int elementOffset2 = Unsafe.Add(ref reference, length - 3); int num4 = Unsafe.Add(ref reference, length - 2); int num5 = Unsafe.Add(ref reference, length - 1); elementOffset = Unsafe.Add(ref reference2, elementOffset); elementOffset2 = Unsafe.Add(ref reference2, elementOffset2); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset |= elementOffset2; if (num5 != 61) { num4 = Unsafe.Add(ref reference2, num4); num5 = Unsafe.Add(ref reference2, num5); num4 <<= 6; elementOffset |= num5; elementOffset |= num4; if (elementOffset >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), elementOffset); num2 += 3; goto IL_016d; } } else if (num4 != 61) { num4 = Unsafe.Add(ref reference2, num4); num4 <<= 6; elementOffset |= num4; if (elementOffset >= 0) { Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16); Unsafe.Add(ref reference, num2 + 1) = (byte)(elementOffset >> 8); num2 += 2; goto IL_016d; } } else if (elementOffset >= 0) { Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16); num2++; goto IL_016d; } } goto IL_0172; IL_0172: bytesWritten = num2; return OperationStatus.InvalidData; IL_016d: bytesWritten = num2; return OperationStatus.Done; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Decode(ref byte encodedBytes, ref sbyte decodingMap) { int elementOffset = encodedBytes; int elementOffset2 = Unsafe.Add(ref encodedBytes, 1); int elementOffset3 = Unsafe.Add(ref encodedBytes, 2); int elementOffset4 = Unsafe.Add(ref encodedBytes, 3); elementOffset = Unsafe.Add(ref decodingMap, elementOffset); elementOffset2 = Unsafe.Add(ref decodingMap, elementOffset2); elementOffset3 = Unsafe.Add(ref decodingMap, elementOffset3); elementOffset4 = Unsafe.Add(ref decodingMap, elementOffset4); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset3 <<= 6; elementOffset |= elementOffset4; elementOffset2 |= elementOffset3; return elementOffset | elementOffset2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteThreeLowOrderBytes(ref byte destination, int value) { destination = (byte)(value >> 16); Unsafe.Add(ref destination, 1) = (byte)(value >> 8); Unsafe.Add(ref destination, 2) = (byte)value; } public static OperationStatus EncodeToUtf8(ReadOnlySpan bytes, Span utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) { ref byte reference = ref MemoryMarshal.GetReference(bytes); ref byte reference2 = ref MemoryMarshal.GetReference(utf8); int length = bytes.Length; int length2 = utf8.Length; int num = 0; num = ((length > 1610612733 || length2 < GetMaxEncodedToUtf8Length(length)) ? ((length2 >> 2) * 3 - 2) : (length - 2)); int i = 0; int num2 = 0; int num3 = 0; ref byte encodingMap = ref s_encodingMap[0]; for (; i < num; i += 3) { num3 = Encode(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; } if (num == length - 2) { if (isFinalBlock) { if (i == length - 1) { num3 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; i++; } else if (i == length - 2) { num3 = EncodeAndPadOne(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; i += 2; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.Done; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.NeedMoreData; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.DestinationTooSmall; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMaxEncodedToUtf8Length(int length) { if ((uint)length > 1610612733u) { System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); } return (length + 2) / 3 * 4; } public static OperationStatus EncodeToUtf8InPlace(Span buffer, int dataLength, out int bytesWritten) { int maxEncodedToUtf8Length = GetMaxEncodedToUtf8Length(dataLength); if (buffer.Length >= maxEncodedToUtf8Length) { int num = dataLength - dataLength / 3 * 3; int num2 = maxEncodedToUtf8Length - 4; int num3 = dataLength - num; int num4 = 0; ref byte encodingMap = ref s_encodingMap[0]; ref byte reference = ref MemoryMarshal.GetReference(buffer); switch (num) { case 1: num4 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; break; default: num4 = EncodeAndPadOne(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; break; case 0: break; } for (num3 -= 3; num3 >= 0; num3 -= 3) { num4 = Encode(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; } bytesWritten = maxEncodedToUtf8Length; return OperationStatus.Done; } bytesWritten = 0; return OperationStatus.DestinationTooSmall; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Encode(ref byte threeBytes, ref byte encodingMap) { int num = (threeBytes << 16) | (Unsafe.Add(ref threeBytes, 1) << 8) | Unsafe.Add(ref threeBytes, 2); int num2 = Unsafe.Add(ref encodingMap, num >> 18); int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 0x3F); int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 0x3F); int num5 = Unsafe.Add(ref encodingMap, num & 0x3F); return num2 | (num3 << 8) | (num4 << 16) | (num5 << 24); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int EncodeAndPadOne(ref byte twoBytes, ref byte encodingMap) { int num = (twoBytes << 16) | (Unsafe.Add(ref twoBytes, 1) << 8); int num2 = Unsafe.Add(ref encodingMap, num >> 18); int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 0x3F); int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 0x3F); return num2 | (num3 << 8) | (num4 << 16) | 0x3D000000; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int EncodeAndPadTwo(ref byte oneByte, ref byte encodingMap) { int num = oneByte << 8; int num2 = Unsafe.Add(ref encodingMap, num >> 10); int num3 = Unsafe.Add(ref encodingMap, (num >> 4) & 0x3F); return num2 | (num3 << 8) | 0x3D0000 | 0x3D000000; } } internal static class FormattingHelpers { public enum HexCasing : uint { Uppercase = 0u, Lowercase = 8224u } internal const string HexTableLower = "0123456789abcdef"; internal const string HexTableUpper = "0123456789ABCDEF"; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(ulong value) { int num = 1; uint num2; if (value >= 10000000) { if (value >= 100000000000000L) { num2 = (uint)(value / 100000000000000L); num += 14; } else { num2 = (uint)(value / 10000000); num += 7; } } else { num2 = (uint)value; } if (num2 >= 10) { num = ((num2 < 100) ? (num + 1) : ((num2 < 1000) ? (num + 2) : ((num2 < 10000) ? (num + 3) : ((num2 < 100000) ? (num + 4) : ((num2 >= 1000000) ? (num + 6) : (num + 5)))))); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(uint value) { int num = 1; if (value >= 100000) { value /= 100000; num += 5; } if (value >= 10) { num = ((value < 100) ? (num + 1) : ((value < 1000) ? (num + 2) : ((value >= 10000) ? (num + 4) : (num + 3)))); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits(ulong value) { int num = 1; if (value > uint.MaxValue) { num += 8; value >>= 32; } if (value > 65535) { num += 4; value >>= 16; } if (value > 255) { num += 2; value >>= 8; } if (value > 15) { num++; } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char GetSymbolOrDefault(in StandardFormat format, char defaultSymbol) { char c = format.Symbol; if (c == '\0' && format.Precision == 0) { c = defaultSymbol; } return c; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FillWithAsciiZeros(Span buffer) { for (int i = 0; i < buffer.Length; i++) { buffer[i] = 48; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteHexByte(byte value, Span buffer, int startingIndex = 0, HexCasing casing = HexCasing.Uppercase) { uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209); uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing; buffer[startingIndex + 1] = (byte)num2; buffer[startingIndex] = (byte)(num2 >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDigits(ulong value, Span buffer) { for (int num = buffer.Length - 1; num >= 1; num--) { ulong num2 = 48 + value; value /= 10; buffer[num] = (byte)(num2 - value * 10); } buffer[0] = (byte)(48 + value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDigitsWithGroupSeparator(ulong value, Span buffer) { int num = 0; for (int num2 = buffer.Length - 1; num2 >= 1; num2--) { ulong num3 = 48 + value; value /= 10; buffer[num2] = (byte)(num3 - value * 10); if (num == 2) { buffer[--num2] = 44; num = 0; } else { num++; } } buffer[0] = (byte)(48 + value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDigits(uint value, Span buffer) { for (int num = buffer.Length - 1; num >= 1; num--) { uint num2 = 48 + value; value /= 10; buffer[num] = (byte)(num2 - value * 10); } buffer[0] = (byte)(48 + value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteFourDecimalDigits(uint value, Span buffer, int startingIndex = 0) { uint num = 48 + value; value /= 10; buffer[startingIndex + 3] = (byte)(num - value * 10); num = 48 + value; value /= 10; buffer[startingIndex + 2] = (byte)(num - value * 10); num = 48 + value; value /= 10; buffer[startingIndex + 1] = (byte)(num - value * 10); buffer[startingIndex] = (byte)(48 + value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTwoDecimalDigits(uint value, Span buffer, int startingIndex = 0) { uint num = 48 + value; value /= 10; buffer[startingIndex + 1] = (byte)(num - value * 10); buffer[startingIndex] = (byte)(48 + value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong DivMod(ulong numerator, ulong denominator, out ulong modulo) { ulong num = numerator / denominator; modulo = numerator - num * denominator; return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint DivMod(uint numerator, uint denominator, out uint modulo) { uint num = numerator / denominator; modulo = numerator - num * denominator; return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros) { int num = 0; if (value != 0) { while (true) { uint modulo; uint num2 = DivMod(value, 10u, out modulo); if (modulo != 0) { break; } value = num2; num++; } } valueWithoutTrailingZeros = value; return num; } } internal static class Utf8Constants { public const byte Colon = 58; public const byte Comma = 44; public const byte Minus = 45; public const byte Period = 46; public const byte Plus = 43; public const byte Slash = 47; public const byte Space = 32; public const byte Hyphen = 45; public const byte Separator = 44; public const int GroupSize = 3; public static readonly TimeSpan s_nullUtcOffset = TimeSpan.MinValue; public const int DateTimeMaxUtcOffsetHours = 14; public const int DateTimeNumFractionDigits = 7; public const int MaxDateTimeFraction = 9999999; public const ulong BillionMaxUIntValue = 4294967295000000000uL; public const uint Billion = 1000000000u; } internal static class Utf8Formatter { [StructLayout(LayoutKind.Explicit)] private struct DecomposedGuid { [FieldOffset(0)] public Guid Guid; [FieldOffset(0)] public byte Byte00; [FieldOffset(1)] public byte Byte01; [FieldOffset(2)] public byte Byte02; [FieldOffset(3)] public byte Byte03; [FieldOffset(4)] public byte Byte04; [FieldOffset(5)] public byte Byte05; [FieldOffset(6)] public byte Byte06; [FieldOffset(7)] public byte Byte07; [FieldOffset(8)] public byte Byte08; [FieldOffset(9)] public byte Byte09; [FieldOffset(10)] public byte Byte10; [FieldOffset(11)] public byte Byte11; [FieldOffset(12)] public byte Byte12; [FieldOffset(13)] public byte Byte13; [FieldOffset(14)] public byte Byte14; [FieldOffset(15)] public byte Byte15; } private const byte TimeMarker = 84; private const byte UtcMarker = 90; private const byte GMT1 = 71; private const byte GMT2 = 77; private const byte GMT3 = 84; private const byte GMT1Lowercase = 103; private const byte GMT2Lowercase = 109; private const byte GMT3Lowercase = 116; private static readonly uint[] DayAbbreviations = new uint[7] { 7238995u, 7237453u, 6649172u, 6579543u, 7694420u, 6910534u, 7627091u }; private static readonly uint[] DayAbbreviationsLowercase = new uint[7] { 7239027u, 7237485u, 6649204u, 6579575u, 7694452u, 6910566u, 7627123u }; private static readonly uint[] MonthAbbreviations = new uint[12] { 7233866u, 6448454u, 7496013u, 7499841u, 7954765u, 7238986u, 7107914u, 6780225u, 7365971u, 7627599u, 7761742u, 6513988u }; private static readonly uint[] MonthAbbreviationsLowercase = new uint[12] { 7233898u, 6448486u, 7496045u, 7499873u, 7954797u, 7239018u, 7107946u, 6780257u, 7366003u, 7627631u, 7761774u, 6514020u }; private const byte OpenBrace = 123; private const byte CloseBrace = 125; private const byte OpenParen = 40; private const byte CloseParen = 41; private const byte Dash = 45; public static bool TryFormat(bool value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { char symbolOrDefault = System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'G'); if (value) { if (symbolOrDefault == 'G') { if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1416787301u)) { goto IL_0033; } } else { if (symbolOrDefault != 'l') { goto IL_0083; } if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1953658213u)) { goto IL_0033; } } } else if (symbolOrDefault == 'G') { if (4u < (uint)destination.Length) { BinaryPrimitives.WriteUInt32BigEndian(destination, 1180789875u); goto IL_006e; } } else { if (symbolOrDefault != 'l') { goto IL_0083; } if (4u < (uint)destination.Length) { BinaryPrimitives.WriteUInt32BigEndian(destination, 1717660787u); goto IL_006e; } } bytesWritten = 0; return false; IL_006e: destination[4] = 101; bytesWritten = 5; return true; IL_0083: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); IL_0033: bytesWritten = 4; return true; } public static bool TryFormat(DateTimeOffset value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { TimeSpan offset = Utf8Constants.s_nullUtcOffset; char c = format.Symbol; if (format.IsDefault) { c = 'G'; offset = value.Offset; } return c switch { 'R' => TryFormatDateTimeR(value.UtcDateTime, destination, out bytesWritten), 'l' => TryFormatDateTimeL(value.UtcDateTime, destination, out bytesWritten), 'O' => TryFormatDateTimeO(value.DateTime, value.Offset, destination, out bytesWritten), 'G' => TryFormatDateTimeG(value.DateTime, offset, destination, out bytesWritten), _ => System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten), }; } public static bool TryFormat(DateTime value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'G') switch { 'R' => TryFormatDateTimeR(value, destination, out bytesWritten), 'l' => TryFormatDateTimeL(value, destination, out bytesWritten), 'O' => TryFormatDateTimeO(value, Utf8Constants.s_nullUtcOffset, destination, out bytesWritten), 'G' => TryFormatDateTimeG(value, Utf8Constants.s_nullUtcOffset, destination, out bytesWritten), _ => System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten), }; } private static bool TryFormatDateTimeG(DateTime value, TimeSpan offset, Span destination, out int bytesWritten) { int num = 19; if (offset != Utf8Constants.s_nullUtcOffset) { num += 7; } if (destination.Length < num) { bytesWritten = 0; return false; } bytesWritten = num; byte b = destination[18]; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, destination); destination[2] = 47; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 3); destination[5] = 47; System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 6); destination[10] = 32; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 11); destination[13] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 14); destination[16] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 17); if (offset != Utf8Constants.s_nullUtcOffset) { byte b2; if (offset < default(TimeSpan)) { b2 = 45; offset = TimeSpan.FromTicks(-offset.Ticks); } else { b2 = 43; } System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, destination, 24); destination[23] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, destination, 21); destination[20] = b2; destination[19] = 32; } return true; } private static bool TryFormatDateTimeL(DateTime value, Span destination, out int bytesWritten) { if (28u >= (uint)destination.Length) { bytesWritten = 0; return false; } uint num = DayAbbreviationsLowercase[(int)value.DayOfWeek]; destination[0] = (byte)num; num >>= 8; destination[1] = (byte)num; num >>= 8; destination[2] = (byte)num; destination[3] = 44; destination[4] = 32; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 5); destination[7] = 32; uint num2 = MonthAbbreviationsLowercase[value.Month - 1]; destination[8] = (byte)num2; num2 >>= 8; destination[9] = (byte)num2; num2 >>= 8; destination[10] = (byte)num2; destination[11] = 32; System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 12); destination[16] = 32; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 17); destination[19] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 20); destination[22] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 23); destination[25] = 32; destination[26] = 103; destination[27] = 109; destination[28] = 116; bytesWritten = 29; return true; } private static bool TryFormatDateTimeO(DateTime value, TimeSpan offset, Span destination, out int bytesWritten) { int num = 27; DateTimeKind dateTimeKind = DateTimeKind.Local; if (offset == Utf8Constants.s_nullUtcOffset) { dateTimeKind = value.Kind; switch (dateTimeKind) { case DateTimeKind.Local: offset = TimeZoneInfo.Local.GetUtcOffset(value); num += 6; break; case DateTimeKind.Utc: num++; break; } } else { num += 6; } if (destination.Length < num) { bytesWritten = 0; return false; } bytesWritten = num; byte b = destination[26]; System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination); destination[4] = 45; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, destination, 5); destination[7] = 45; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 8); destination[10] = 84; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 11); destination[13] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 14); destination[16] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 17); destination[19] = 46; System.Buffers.Text.FormattingHelpers.WriteDigits((uint)((ulong)value.Ticks % 10000000uL), destination.Slice(20, 7)); switch (dateTimeKind) { case DateTimeKind.Local: { byte b2; if (offset < default(TimeSpan)) { b2 = 45; offset = TimeSpan.FromTicks(-offset.Ticks); } else { b2 = 43; } System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, destination, 31); destination[30] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, destination, 28); destination[27] = b2; break; } case DateTimeKind.Utc: destination[27] = 90; break; } return true; } private static bool TryFormatDateTimeR(DateTime value, Span destination, out int bytesWritten) { if (28u >= (uint)destination.Length) { bytesWritten = 0; return false; } uint num = DayAbbreviations[(int)value.DayOfWeek]; destination[0] = (byte)num; num >>= 8; destination[1] = (byte)num; num >>= 8; destination[2] = (byte)num; destination[3] = 44; destination[4] = 32; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 5); destination[7] = 32; uint num2 = MonthAbbreviations[value.Month - 1]; destination[8] = (byte)num2; num2 >>= 8; destination[9] = (byte)num2; num2 >>= 8; destination[10] = (byte)num2; destination[11] = 32; System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 12); destination[16] = 32; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 17); destination[19] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 20); destination[22] = 58; System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 23); destination[25] = 32; destination[26] = 71; destination[27] = 77; destination[28] = 84; bytesWritten = 29; return true; } public static bool TryFormat(decimal value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { if (format.IsDefault) { format = 'G'; } switch (format.Symbol) { case 'G': case 'g': { if (format.Precision != byte.MaxValue) { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_GWithPrecisionNotSupported); } NumberBuffer number3 = default(NumberBuffer); System.Number.DecimalToNumber(value, ref number3); if (number3.Digits[0] == 0) { number3.IsNegative = false; } return TryFormatDecimalG(ref number3, destination, out bytesWritten); } case 'F': case 'f': { NumberBuffer number2 = default(NumberBuffer); System.Number.DecimalToNumber(value, ref number2); byte b2 = (byte)((format.Precision == byte.MaxValue) ? 2 : format.Precision); System.Number.RoundNumber(ref number2, number2.Scale + b2); return TryFormatDecimalF(ref number2, destination, out bytesWritten, b2); } case 'E': case 'e': { NumberBuffer number = default(NumberBuffer); System.Number.DecimalToNumber(value, ref number); byte b = (byte)((format.Precision == byte.MaxValue) ? 6 : format.Precision); System.Number.RoundNumber(ref number, b + 1); return TryFormatDecimalE(ref number, destination, out bytesWritten, b, (byte)format.Symbol); } default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); } } private static bool TryFormatDecimalE(ref NumberBuffer number, Span destination, out int bytesWritten, byte precision, byte exponentSymbol) { int scale = number.Scale; ReadOnlySpan readOnlySpan = number.Digits; int num = (number.IsNegative ? 1 : 0) + 1 + ((precision != 0) ? (precision + 1) : 0) + 2 + 3; if (destination.Length < num) { bytesWritten = 0; return false; } int num2 = 0; int num3 = 0; if (number.IsNegative) { destination[num2++] = 45; } byte b = readOnlySpan[num3]; int num4; if (b == 0) { destination[num2++] = 48; num4 = 0; } else { destination[num2++] = b; num3++; num4 = scale - 1; } if (precision > 0) { destination[num2++] = 46; for (int i = 0; i < precision; i++) { byte b2 = readOnlySpan[num3]; if (b2 == 0) { while (i++ < precision) { destination[num2++] = 48; } break; } destination[num2++] = b2; num3++; } } destination[num2++] = exponentSymbol; if (num4 >= 0) { destination[num2++] = 43; } else { destination[num2++] = 45; num4 = -num4; } destination[num2++] = 48; destination[num2++] = (byte)(num4 / 10 + 48); destination[num2++] = (byte)(num4 % 10 + 48); bytesWritten = num; return true; } private static bool TryFormatDecimalF(ref NumberBuffer number, Span destination, out int bytesWritten, byte precision) { int scale = number.Scale; ReadOnlySpan readOnlySpan = number.Digits; int num = (number.IsNegative ? 1 : 0) + ((scale <= 0) ? 1 : scale) + ((precision != 0) ? (precision + 1) : 0); if (destination.Length < num) { bytesWritten = 0; return false; } int i = 0; int num2 = 0; if (number.IsNegative) { destination[num2++] = 45; } if (scale <= 0) { destination[num2++] = 48; } else { for (; i < scale; i++) { byte b = readOnlySpan[i]; if (b == 0) { int num3 = scale - i; for (int j = 0; j < num3; j++) { destination[num2++] = 48; } break; } destination[num2++] = b; } } if (precision > 0) { destination[num2++] = 46; int k = 0; if (scale < 0) { int num4 = Math.Min(precision, -scale); for (int l = 0; l < num4; l++) { destination[num2++] = 48; } k += num4; } for (; k < precision; k++) { byte b2 = readOnlySpan[i]; if (b2 == 0) { while (k++ < precision) { destination[num2++] = 48; } break; } destination[num2++] = b2; i++; } } bytesWritten = num; return true; } private static bool TryFormatDecimalG(ref NumberBuffer number, Span destination, out int bytesWritten) { int scale = number.Scale; ReadOnlySpan readOnlySpan = number.Digits; int numDigits = number.NumDigits; bool flag = scale < numDigits; int num; if (flag) { num = numDigits + 1; if (scale <= 0) { num += 1 + -scale; } } else { num = ((scale <= 0) ? 1 : scale); } if (number.IsNegative) { num++; } if (destination.Length < num) { bytesWritten = 0; return false; } int i = 0; int num2 = 0; if (number.IsNegative) { destination[num2++] = 45; } if (scale <= 0) { destination[num2++] = 48; } else { for (; i < scale; i++) { byte b = readOnlySpan[i]; if (b == 0) { int num3 = scale - i; for (int j = 0; j < num3; j++) { destination[num2++] = 48; } break; } destination[num2++] = b; } } if (flag) { destination[num2++] = 46; if (scale < 0) { int num4 = -scale; for (int k = 0; k < num4; k++) { destination[num2++] = 48; } } byte b2; while ((b2 = readOnlySpan[i++]) != 0) { destination[num2++] = b2; } } bytesWritten = num; return true; } public static bool TryFormat(double value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatFloatingPoint(value, destination, out bytesWritten, format); } public static bool TryFormat(float value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatFloatingPoint(value, destination, out bytesWritten, format); } private static bool TryFormatFloatingPoint(T value, Span destination, out int bytesWritten, StandardFormat format) where T : IFormattable { if (format.IsDefault) { format = 'G'; } switch (format.Symbol) { case 'G': case 'g': if (format.Precision != byte.MaxValue) { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_GWithPrecisionNotSupported); } break; default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); case 'E': case 'F': case 'e': case 'f': break; } string text = format.ToString(); string text2 = value.ToString(text, CultureInfo.InvariantCulture); int length = text2.Length; if (length > destination.Length) { bytesWritten = 0; return false; } for (int i = 0; i < length; i++) { destination[i] = (byte)text2[i]; } bytesWritten = length; return true; } public static bool TryFormat(Guid value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { int num; switch (System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'D')) { case 'D': num = -2147483612; break; case 'B': num = -2139260122; break; case 'P': num = -2144786394; break; case 'N': num = 32; break; default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); } if ((byte)num > destination.Length) { bytesWritten = 0; return false; } bytesWritten = (byte)num; num >>= 8; if ((byte)num != 0) { destination[0] = (byte)num; destination = destination.Slice(1); } num >>= 8; DecomposedGuid decomposedGuid = new DecomposedGuid { Guid = value }; byte b = destination[8]; System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte03, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte02, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte01, destination, 4, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte00, destination, 6, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); if (num < 0) { destination[8] = 45; destination = destination.Slice(9); } else { destination = destination.Slice(8); } byte b2 = destination[4]; System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte05, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte04, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); if (num < 0) { destination[4] = 45; destination = destination.Slice(5); } else { destination = destination.Slice(4); } byte b3 = destination[4]; System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte07, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte06, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); if (num < 0) { destination[4] = 45; destination = destination.Slice(5); } else { destination = destination.Slice(4); } byte b4 = destination[4]; System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte08, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte09, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); if (num < 0) { destination[4] = 45; destination = destination.Slice(5); } else { destination = destination.Slice(4); } byte b5 = destination[11]; System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte10, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte11, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte12, destination, 4, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte13, destination, 6, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte14, destination, 8, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte15, destination, 10, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase); if ((byte)num != 0) { destination[12] = (byte)num; } return true; } public static bool TryFormat(byte value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatUInt64(value, destination, out bytesWritten, format); } [CLSCompliant(false)] public static bool TryFormat(sbyte value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatInt64(value, 255uL, destination, out bytesWritten, format); } [CLSCompliant(false)] public static bool TryFormat(ushort value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatUInt64(value, destination, out bytesWritten, format); } public static bool TryFormat(short value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatInt64(value, 65535uL, destination, out bytesWritten, format); } [CLSCompliant(false)] public static bool TryFormat(uint value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatUInt64(value, destination, out bytesWritten, format); } public static bool TryFormat(int value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatInt64(value, 4294967295uL, destination, out bytesWritten, format); } [CLSCompliant(false)] public static bool TryFormat(ulong value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatUInt64(value, destination, out bytesWritten, format); } public static bool TryFormat(long value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { return TryFormatInt64(value, ulong.MaxValue, destination, out bytesWritten, format); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt64(long value, ulong mask, Span destination, out int bytesWritten, StandardFormat format) { if (format.IsDefault) { return TryFormatInt64Default(value, destination, out bytesWritten); } switch (format.Symbol) { case 'G': case 'g': if (format.HasPrecision) { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_GWithPrecisionNotSupported); } return TryFormatInt64D(value, format.Precision, destination, out bytesWritten); case 'D': case 'd': return TryFormatInt64D(value, format.Precision, destination, out bytesWritten); case 'N': case 'n': return TryFormatInt64N(value, format.Precision, destination, out bytesWritten); case 'x': return TryFormatUInt64X((ulong)value & mask, format.Precision, useLower: true, destination, out bytesWritten); case 'X': return TryFormatUInt64X((ulong)value & mask, format.Precision, useLower: false, destination, out bytesWritten); default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt64D(long value, byte precision, Span destination, out int bytesWritten) { bool insertNegationSign = false; if (value < 0) { insertNegationSign = true; value = -value; } return TryFormatUInt64D((ulong)value, precision, destination, insertNegationSign, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt64Default(long value, Span destination, out int bytesWritten) { if ((ulong)value < 10uL) { return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); } if (IntPtr.Size == 8) { return TryFormatInt64MultipleDigits(value, destination, out bytesWritten); } if (value <= int.MaxValue && value >= int.MinValue) { return TryFormatInt32MultipleDigits((int)value, destination, out bytesWritten); } if (value <= 4294967295000000000L && value >= -4294967295000000000L) { if (value >= 0) { return TryFormatUInt64LessThanBillionMaxUInt((ulong)value, destination, out bytesWritten); } return TryFormatInt64MoreThanNegativeBillionMaxUInt(-value, destination, out bytesWritten); } if (value >= 0) { return TryFormatUInt64MoreThanBillionMaxUInt((ulong)value, destination, out bytesWritten); } return TryFormatInt64LessThanNegativeBillionMaxUInt(-value, destination, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt32Default(int value, Span destination, out int bytesWritten) { if ((uint)value < 10u) { return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); } return TryFormatInt32MultipleDigits(value, destination, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt32MultipleDigits(int value, Span destination, out int bytesWritten) { if (value < 0) { value = -value; int num = System.Buffers.Text.FormattingHelpers.CountDigits((uint)value); if (num >= destination.Length) { bytesWritten = 0; return false; } destination[0] = 45; bytesWritten = num + 1; System.Buffers.Text.FormattingHelpers.WriteDigits((uint)value, destination.Slice(1, num)); return true; } return TryFormatUInt32MultipleDigits((uint)value, destination, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt64MultipleDigits(long value, Span destination, out int bytesWritten) { if (value < 0) { value = -value; int num = System.Buffers.Text.FormattingHelpers.CountDigits((ulong)value); if (num >= destination.Length) { bytesWritten = 0; return false; } destination[0] = 45; bytesWritten = num + 1; System.Buffers.Text.FormattingHelpers.WriteDigits((ulong)value, destination.Slice(1, num)); return true; } return TryFormatUInt64MultipleDigits((ulong)value, destination, out bytesWritten); } private static bool TryFormatInt64MoreThanNegativeBillionMaxUInt(long value, Span destination, out int bytesWritten) { uint num = (uint)(value / 1000000000); uint value2 = (uint)(value - num * 1000000000); int num2 = System.Buffers.Text.FormattingHelpers.CountDigits(num); int num3 = num2 + 9; if (num3 >= destination.Length) { bytesWritten = 0; return false; } destination[0] = 45; bytesWritten = num3 + 1; System.Buffers.Text.FormattingHelpers.WriteDigits(num, destination.Slice(1, num2)); System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num2 + 1, 9)); return true; } private static bool TryFormatInt64LessThanNegativeBillionMaxUInt(long value, Span destination, out int bytesWritten) { ulong num = (ulong)value / 1000000000uL; uint value2 = (uint)((ulong)value - num * 1000000000); uint num2 = (uint)(num / 1000000000); uint value3 = (uint)(num - num2 * 1000000000); int num3 = System.Buffers.Text.FormattingHelpers.CountDigits(num2); int num4 = num3 + 18; if (num4 >= destination.Length) { bytesWritten = 0; return false; } destination[0] = 45; bytesWritten = num4 + 1; System.Buffers.Text.FormattingHelpers.WriteDigits(num2, destination.Slice(1, num3)); System.Buffers.Text.FormattingHelpers.WriteDigits(value3, destination.Slice(num3 + 1, 9)); System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num3 + 1 + 9, 9)); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatInt64N(long value, byte precision, Span destination, out int bytesWritten) { bool insertNegationSign = false; if (value < 0) { insertNegationSign = true; value = -value; } return TryFormatUInt64N((ulong)value, precision, destination, insertNegationSign, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt64(ulong value, Span destination, out int bytesWritten, StandardFormat format) { if (format.IsDefault) { return TryFormatUInt64Default(value, destination, out bytesWritten); } switch (format.Symbol) { case 'G': case 'g': if (format.HasPrecision) { throw new NotSupportedException(<27c7dfb4-b639-4500-8914-8d6e6caca8cb>SR.Argument_GWithPrecisionNotSupported); } return TryFormatUInt64D(value, format.Precision, destination, insertNegationSign: false, out bytesWritten); case 'D': case 'd': return TryFormatUInt64D(value, format.Precision, destination, insertNegationSign: false, out bytesWritten); case 'N': case 'n': return TryFormatUInt64N(value, format.Precision, destination, insertNegationSign: false, out bytesWritten); case 'x': return TryFormatUInt64X(value, format.Precision, useLower: true, destination, out bytesWritten); case 'X': return TryFormatUInt64X(value, format.Precision, useLower: false, destination, out bytesWritten); default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); } } private static bool TryFormatUInt64D(ulong value, byte precision, Span destination, bool insertNegationSign, out int bytesWritten) { int num = System.Buffers.Text.FormattingHelpers.CountDigits(value); int num2 = ((precision != byte.MaxValue) ? precision : 0) - num; if (num2 < 0) { num2 = 0; } int num3 = num + num2; if (insertNegationSign) { num3++; } if (num3 > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num3; if (insertNegationSign) { destination[0] = 45; destination = destination.Slice(1); } if (num2 > 0) { System.Buffers.Text.FormattingHelpers.FillWithAsciiZeros(destination.Slice(0, num2)); } System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(num2, num)); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt64Default(ulong value, Span destination, out int bytesWritten) { if (value < 10) { return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); } if (IntPtr.Size == 8) { return TryFormatUInt64MultipleDigits(value, destination, out bytesWritten); } if (value <= uint.MaxValue) { return TryFormatUInt32MultipleDigits((uint)value, destination, out bytesWritten); } if (value <= 4294967295000000000L) { return TryFormatUInt64LessThanBillionMaxUInt(value, destination, out bytesWritten); } return TryFormatUInt64MoreThanBillionMaxUInt(value, destination, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt32Default(uint value, Span destination, out int bytesWritten) { if (value < 10) { return TryFormatUInt32SingleDigit(value, destination, out bytesWritten); } return TryFormatUInt32MultipleDigits(value, destination, out bytesWritten); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt32SingleDigit(uint value, Span destination, out int bytesWritten) { if (destination.Length == 0) { bytesWritten = 0; return false; } destination[0] = (byte)(48 + value); bytesWritten = 1; return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt32MultipleDigits(uint value, Span destination, out int bytesWritten) { int num = System.Buffers.Text.FormattingHelpers.CountDigits(value); if (num > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num; System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(0, num)); return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt64SingleDigit(ulong value, Span destination, out int bytesWritten) { if (destination.Length == 0) { bytesWritten = 0; return false; } destination[0] = (byte)(48 + value); bytesWritten = 1; return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryFormatUInt64MultipleDigits(ulong value, Span destination, out int bytesWritten) { int num = System.Buffers.Text.FormattingHelpers.CountDigits(value); if (num > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num; System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(0, num)); return true; } private static bool TryFormatUInt64LessThanBillionMaxUInt(ulong value, Span destination, out int bytesWritten) { uint num = (uint)(value / 1000000000); uint value2 = (uint)(value - num * 1000000000); int num2 = System.Buffers.Text.FormattingHelpers.CountDigits(num); int num3 = num2 + 9; if (num3 > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num3; System.Buffers.Text.FormattingHelpers.WriteDigits(num, destination.Slice(0, num2)); System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num2, 9)); return true; } private static bool TryFormatUInt64MoreThanBillionMaxUInt(ulong value, Span destination, out int bytesWritten) { ulong num = value / 1000000000; uint value2 = (uint)(value - num * 1000000000); uint num2 = (uint)(num / 1000000000); uint value3 = (uint)(num - num2 * 1000000000); int num3 = System.Buffers.Text.FormattingHelpers.CountDigits(num2); int num4 = num3 + 18; if (num4 > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num4; System.Buffers.Text.FormattingHelpers.WriteDigits(num2, destination.Slice(0, num3)); System.Buffers.Text.FormattingHelpers.WriteDigits(value3, destination.Slice(num3, 9)); System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num3 + 9, 9)); return true; } private static bool TryFormatUInt64N(ulong value, byte precision, Span destination, bool insertNegationSign, out int bytesWritten) { int num = System.Buffers.Text.FormattingHelpers.CountDigits(value); int num2 = (num - 1) / 3; int num3 = ((precision == byte.MaxValue) ? 2 : precision); int num4 = num + num2; if (num3 > 0) { num4 += num3 + 1; } if (insertNegationSign) { num4++; } if (num4 > destination.Length) { bytesWritten = 0; return false; } bytesWritten = num4; if (insertNegationSign) { destination[0] = 45; destination = destination.Slice(1); } System.Buffers.Text.FormattingHelpers.WriteDigitsWithGroupSeparator(value, destination.Slice(0, num + num2)); if (num3 > 0) { destination[num + num2] = 46; System.Buffers.Text.FormattingHelpers.FillWithAsciiZeros(destination.Slice(num + num2 + 1, num3)); } return true; } private static bool TryFormatUInt64X(ulong value, byte precision, bool useLower, Span destination, out int bytesWritten) { int num = System.Buffers.Text.FormattingHelpers.CountHexDigits(value); int num2 = ((precision == byte.MaxValue) ? num : Math.Max(precision, num)); if (destination.Length < num2) { bytesWritten = 0; return false; } bytesWritten = num2; string text = (useLower ? "0123456789abcdef" : "0123456789ABCDEF"); while ((uint)(--num2) < (uint)destination.Length) { destination[num2] = (byte)text[(int)value & 0xF]; value >>= 4; } return true; } public static bool TryFormat(TimeSpan value, Span destination, out int bytesWritten, StandardFormat format = default(StandardFormat)) { char c = System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'c'); switch (c) { case 'T': case 't': c = 'c'; break; default: return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten); case 'G': case 'c': case 'g': break; } int num = 8; long ticks = value.Ticks; uint valueWithoutTrailingZeros; ulong num2; if (ticks < 0) { ticks = -ticks; if (ticks < 0) { valueWithoutTrailingZeros = 4775808u; num2 = 922337203685uL; goto IL_0082; } } num2 = System.Buffers.Text.FormattingHelpers.DivMod((ulong)Math.Abs(value.Ticks), 10000000uL, out var modulo); valueWithoutTrailingZeros = (uint)modulo; goto IL_0082; IL_0082: int num3 = 0; switch (c) { case 'c': if (valueWithoutTrailingZeros != 0) { num3 = 7; } break; case 'G': num3 = 7; break; default: if (valueWithoutTrailingZeros != 0) { num3 = 7 - System.Buffers.Text.FormattingHelpers.CountDecimalTrailingZeros(valueWithoutTrailingZeros, out valueWithoutTrailingZeros); } break; } if (num3 != 0) { num += num3 + 1; } ulong num4 = 0uL; ulong modulo2 = 0uL; if (num2 != 0) { num4 = System.Buffers.Text.FormattingHelpers.DivMod(num2, 60uL, out modulo2); } ulong num5 = 0uL; ulong modulo3 = 0uL; if (num4 != 0) { num5 = System.Buffers.Text.FormattingHelpers.DivMod(num4, 60uL, out modulo3); } uint num6 = 0u; uint modulo4 = 0u; if (num5 != 0) { num6 = System.Buffers.Text.FormattingHelpers.DivMod((uint)num5, 24u, out modulo4); } int num7 = 2; if (modulo4 < 10 && c == 'g') { num7--; num--; } int num8 = 0; if (num6 == 0) { if (c == 'G') { num += 2; num8 = 1; } } else { num8 = System.Buffers.Text.FormattingHelpers.CountDigits(num6); num += num8 + 1; } if (value.Ticks < 0) { num++; } if (destination.Length < num) { bytesWritten = 0; return false; } bytesWritten = num; int num9 = 0; if (value.Ticks < 0) { destination[num9++] = 45; } if (num8 > 0) { System.Buffers.Text.FormattingHelpers.WriteDigits(num6, destination.Slice(num9, num8)); num9 += num8; destination[num9++] = (byte)((c == 'c') ? 46 : 58); } System.Buffers.Text.FormattingHelpers.WriteDigits(modulo4, destination.Slice(num9, num7)); num9 += num7; destination[num9++] = 58; System.Buffers.Text.FormattingHelpers.WriteDigits((uint)modulo3, destination.Slice(num9, 2)); num9 += 2; destination[num9++] = 58; System.Buffers.Text.FormattingHelpers.WriteDigits((uint)modulo2, destination.Slice(num9, 2)); num9 += 2; if (num3 > 0) { destination[num9++] = 46; System.Buffers.Text.FormattingHelpers.WriteDigits(valueWithoutTrailingZeros, destination.Slice(num9, num3)); num9 += num3; } return true; } } internal static class ParserHelpers { public const int ByteOverflowLength = 3; public const int ByteOverflowLengthHex = 2; public const int UInt16OverflowLength = 5; public const int UInt16OverflowLengthHex = 4; public const int UInt32OverflowLength = 10; public const int UInt32OverflowLengthHex = 8; public const int UInt64OverflowLength = 20; public const int UInt64OverflowLengthHex = 16; public const int SByteOverflowLength = 3; public const int SByteOverflowLengthHex = 2; public const int Int16OverflowLength = 5; public const int Int16OverflowLengthHex = 4; public const int Int32OverflowLength = 10; public const int Int32OverflowLengthHex = 8; public const int Int64OverflowLength = 19; public const int Int64OverflowLengthHex = 16; public static readonly byte[] s_hexLookup = new byte[256] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsDigit(int i) { return (uint)(i - 48) <= 9u; } } internal static class Utf8Parser { [Flags] private enum ParseNumberOptions { AllowExponent = 1 } private enum ComponentParseResult : byte { NoMoreData, Colon, Period, ParseFailure } private struct TimeSpanSplitter { public uint V1; public uint V2; public uint V3; public uint V4; public uint V5; public bool IsNegative; public uint Separators; public bool TrySplitTimeSpan(ReadOnlySpan source, bool periodUsedToSeparateDay, out int bytesConsumed) { int i = 0; byte b = 0; for (; i != source.Length; i++) { b = source[i]; if (b != 32 && b != 9) { break; } } if (i == source.Length) { bytesConsumed = 0; return false; } if (b == 45) { IsNegative = true; i++; if (i == source.Length) { bytesConsumed = 0; return false; } } if (!TryParseUInt32D(source.Slice(i), out V1, out var bytesConsumed2)) { bytesConsumed = 0; return false; } i += bytesConsumed2; ComponentParseResult componentParseResult = ParseComponent(source, periodUsedToSeparateDay, ref i, out V2); switch (componentParseResult) { case ComponentParseResult.ParseFailure: bytesConsumed = 0; return false; case ComponentParseResult.NoMoreData: bytesConsumed = i; return true; default: Separators |= (uint)componentParseResult << 24; componentParseResult = ParseComponent(source, neverParseAsFraction: false, ref i, out V3); switch (componentParseResult) { case ComponentParseResult.ParseFailure: bytesConsumed = 0; return false; case ComponentParseResult.NoMoreData: bytesConsumed = i; return true; default: Separators |= (uint)componentParseResult << 16; componentParseResult = ParseComponent(source, neverParseAsFraction: false, ref i, out V4); switch (componentParseResult) { case ComponentParseResult.ParseFailure: bytesConsumed = 0; return false; case ComponentParseResult.NoMoreData: bytesConsumed = i; return true; default: Separators |= (uint)componentParseResult << 8; componentParseResult = ParseComponent(source, neverParseAsFraction: false, ref i, out V5); switch (componentParseResult) { case ComponentParseResult.ParseFailure: bytesConsumed = 0; return false; case ComponentParseResult.NoMoreData: bytesConsumed = i; return true; default: Separators |= (uint)componentParseResult; if (i != source.Length && (source[i] == 46 || source[i] == 58)) { bytesConsumed = 0; return false; } bytesConsumed = i; return true; } } } } } private static ComponentParseResult ParseComponent(ReadOnlySpan source, bool neverParseAsFraction, ref int srcIndex, out uint value) { if (srcIndex == source.Length) { value = 0u; return ComponentParseResult.NoMoreData; } byte b = source[srcIndex]; if (b == 58 || (b == 46 && neverParseAsFraction)) { srcIndex++; if (!TryParseUInt32D(source.Slice(srcIndex), out value, out var bytesConsumed)) { value = 0u; return ComponentParseResult.ParseFailure; } srcIndex += bytesConsumed; if (b != 58) { return ComponentParseResult.Period; } return ComponentParseResult.Colon; } if (b == 46) { srcIndex++; if (!TryParseTimeSpanFraction(source.Slice(srcIndex), out value, out var bytesConsumed2)) { value = 0u; return ComponentParseResult.ParseFailure; } srcIndex += bytesConsumed2; return ComponentParseResult.Period; } value = 0u; return ComponentParseResult.NoMoreData; } } private const uint FlipCase = 32u; private const uint NoFlipCase = 0u; private static readonly int[] s_daysToMonth365 = new int[13] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; private static readonly int[] s_daysToMonth366 = new int[13] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; public static bool TryParse(ReadOnlySpan source, out bool value, out int bytesConsumed, char standardFormat = '\0') { if (standardFormat != 0 && standardFormat != 'G' && standardFormat != 'l') { return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } if (source.Length >= 4) { if ((source[0] == 84 || source[0] == 116) && (source[1] == 82 || source[1] == 114) && (source[2] == 85 || source[2] == 117) && (source[3] == 69 || source[3] == 101)) { bytesConsumed = 4; value = true; return true; } if (source.Length >= 5 && (source[0] == 70 || source[0] == 102) && (source[1] == 65 || source[1] == 97) && (source[2] == 76 || source[2] == 108) && (source[3] == 83 || source[3] == 115) && (source[4] == 69 || source[4] == 101)) { bytesConsumed = 5; value = false; return true; } } bytesConsumed = 0; value = false; return false; } public static bool TryParse(ReadOnlySpan source, out DateTime value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case 'R': { if (!TryParseDateTimeOffsetR(source, 0u, out var dateTimeOffset, out bytesConsumed)) { value = default(DateTime); return false; } value = dateTimeOffset.DateTime; return true; } case 'l': { if (!TryParseDateTimeOffsetR(source, 32u, out var dateTimeOffset2, out bytesConsumed)) { value = default(DateTime); return false; } value = dateTimeOffset2.DateTime; return true; } case 'O': { if (!TryParseDateTimeOffsetO(source, out var value2, out bytesConsumed, out var kind)) { value = default(DateTime); bytesConsumed = 0; return false; } switch (kind) { case DateTimeKind.Local: value = value2.LocalDateTime; break; case DateTimeKind.Utc: value = value2.UtcDateTime; break; default: value = value2.DateTime; break; } return true; } case '\0': case 'G': { DateTimeOffset valueAsOffset; return TryParseDateTimeG(source, out value, out valueAsOffset, out bytesConsumed); } default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } public static bool TryParse(ReadOnlySpan source, out DateTimeOffset value, out int bytesConsumed, char standardFormat = '\0') { DateTimeKind kind; DateTime value2; return standardFormat switch { 'R' => TryParseDateTimeOffsetR(source, 0u, out value, out bytesConsumed), 'l' => TryParseDateTimeOffsetR(source, 32u, out value, out bytesConsumed), 'O' => TryParseDateTimeOffsetO(source, out value, out bytesConsumed, out kind), '\0' => TryParseDateTimeOffsetDefault(source, out value, out bytesConsumed), 'G' => TryParseDateTimeG(source, out value2, out value, out bytesConsumed), _ => System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed), }; } private static bool TryParseDateTimeOffsetDefault(ReadOnlySpan source, out DateTimeOffset value, out int bytesConsumed) { if (source.Length < 26) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } if (!TryParseDateTimeG(source, out var value2, out var _, out var _)) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } if (source[19] != 32) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } byte b = source[20]; if (b != 43 && b != 45) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } uint num = (uint)(source[21] - 48); uint num2 = (uint)(source[22] - 48); if (num > 9 || num2 > 9) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } int num3 = (int)(num * 10 + num2); if (source[23] != 58) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } uint num4 = (uint)(source[24] - 48); uint num5 = (uint)(source[25] - 48); if (num4 > 9 || num5 > 9) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } int num6 = (int)(num4 * 10 + num5); TimeSpan timeSpan = new TimeSpan(num3, num6, 0); if (b == 45) { timeSpan = -timeSpan; } if (!TryCreateDateTimeOffset(value2, b == 45, num3, num6, out value)) { bytesConsumed = 0; value = default(DateTimeOffset); return false; } bytesConsumed = 26; return true; } private static bool TryParseDateTimeG(ReadOnlySpan source, out DateTime value, out DateTimeOffset valueAsOffset, out int bytesConsumed) { if (source.Length < 19) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num = (uint)(source[0] - 48); uint num2 = (uint)(source[1] - 48); if (num > 9 || num2 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int month = (int)(num * 10 + num2); if (source[2] != 47) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num3 = (uint)(source[3] - 48); uint num4 = (uint)(source[4] - 48); if (num3 > 9 || num4 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int day = (int)(num3 * 10 + num4); if (source[5] != 47) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num5 = (uint)(source[6] - 48); uint num6 = (uint)(source[7] - 48); uint num7 = (uint)(source[8] - 48); uint num8 = (uint)(source[9] - 48); if (num5 > 9 || num6 > 9 || num7 > 9 || num8 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int year = (int)(num5 * 1000 + num6 * 100 + num7 * 10 + num8); if (source[10] != 32) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num9 = (uint)(source[11] - 48); uint num10 = (uint)(source[12] - 48); if (num9 > 9 || num10 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int hour = (int)(num9 * 10 + num10); if (source[13] != 58) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num11 = (uint)(source[14] - 48); uint num12 = (uint)(source[15] - 48); if (num11 > 9 || num12 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int minute = (int)(num11 * 10 + num12); if (source[16] != 58) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } uint num13 = (uint)(source[17] - 48); uint num14 = (uint)(source[18] - 48); if (num13 > 9 || num14 > 9) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } int second = (int)(num13 * 10 + num14); if (!TryCreateDateTimeOffsetInterpretingDataAsLocalTime(year, month, day, hour, minute, second, 0, out valueAsOffset)) { bytesConsumed = 0; value = default(DateTime); valueAsOffset = default(DateTimeOffset); return false; } bytesConsumed = 19; value = valueAsOffset.DateTime; return true; } private static bool TryCreateDateTimeOffset(DateTime dateTime, bool offsetNegative, int offsetHours, int offsetMinutes, out DateTimeOffset value) { if ((uint)offsetHours > 14u) { value = default(DateTimeOffset); return false; } if ((uint)offsetMinutes > 59u) { value = default(DateTimeOffset); return false; } if (offsetHours == 14 && offsetMinutes != 0) { value = default(DateTimeOffset); return false; } long num = ((long)offsetHours * 3600L + (long)offsetMinutes * 60L) * 10000000; if (offsetNegative) { num = -num; } try { value = new DateTimeOffset(dateTime.Ticks, new TimeSpan(num)); } catch (ArgumentOutOfRangeException) { value = default(DateTimeOffset); return false; } return true; } private static bool TryCreateDateTimeOffset(int year, int month, int day, int hour, int minute, int second, int fraction, bool offsetNegative, int offsetHours, int offsetMinutes, out DateTimeOffset value) { if (!TryCreateDateTime(year, month, day, hour, minute, second, fraction, DateTimeKind.Unspecified, out var value2)) { value = default(DateTimeOffset); return false; } if (!TryCreateDateTimeOffset(value2, offsetNegative, offsetHours, offsetMinutes, out value)) { value = default(DateTimeOffset); return false; } return true; } private static bool TryCreateDateTimeOffsetInterpretingDataAsLocalTime(int year, int month, int day, int hour, int minute, int second, int fraction, out DateTimeOffset value) { if (!TryCreateDateTime(year, month, day, hour, minute, second, fraction, DateTimeKind.Local, out var value2)) { value = default(DateTimeOffset); return false; } try { value = new DateTimeOffset(value2); } catch (ArgumentOutOfRangeException) { value = default(DateTimeOffset); return false; } return true; } private static bool TryCreateDateTime(int year, int month, int day, int hour, int minute, int second, int fraction, DateTimeKind kind, out DateTime value) { if (year == 0) { value = default(DateTime); return false; } if ((uint)(month - 1) >= 12u) { value = default(DateTime); return false; } uint num = (uint)(day - 1); if (num >= 28 && num >= DateTime.DaysInMonth(year, month)) { value = default(DateTime); return false; } if ((uint)hour > 23u) { value = default(DateTime); return false; } if ((uint)minute > 59u) { value = default(DateTime); return false; } if ((uint)second > 59u) { value = default(DateTime); return false; } int[] array = (DateTime.IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365); int num2 = year - 1; int num3 = num2 * 365 + num2 / 4 - num2 / 100 + num2 / 400 + array[month - 1] + day - 1; long num4 = num3 * 864000000000L; int num5 = hour * 3600 + minute * 60 + second; num4 += (long)num5 * 10000000L; num4 += fraction; value = new DateTime(num4, kind); return true; } private static bool TryParseDateTimeOffsetO(ReadOnlySpan source, out DateTimeOffset value, out int bytesConsumed, out DateTimeKind kind) { if (source.Length < 27) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num = (uint)(source[0] - 48); uint num2 = (uint)(source[1] - 48); uint num3 = (uint)(source[2] - 48); uint num4 = (uint)(source[3] - 48); if (num > 9 || num2 > 9 || num3 > 9 || num4 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int year = (int)(num * 1000 + num2 * 100 + num3 * 10 + num4); if (source[4] != 45) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num5 = (uint)(source[5] - 48); uint num6 = (uint)(source[6] - 48); if (num5 > 9 || num6 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int month = (int)(num5 * 10 + num6); if (source[7] != 45) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num7 = (uint)(source[8] - 48); uint num8 = (uint)(source[9] - 48); if (num7 > 9 || num8 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int day = (int)(num7 * 10 + num8); if (source[10] != 84) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num9 = (uint)(source[11] - 48); uint num10 = (uint)(source[12] - 48); if (num9 > 9 || num10 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int hour = (int)(num9 * 10 + num10); if (source[13] != 58) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num11 = (uint)(source[14] - 48); uint num12 = (uint)(source[15] - 48); if (num11 > 9 || num12 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int minute = (int)(num11 * 10 + num12); if (source[16] != 58) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num13 = (uint)(source[17] - 48); uint num14 = (uint)(source[18] - 48); if (num13 > 9 || num14 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int second = (int)(num13 * 10 + num14); if (source[19] != 46) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num15 = (uint)(source[20] - 48); uint num16 = (uint)(source[21] - 48); uint num17 = (uint)(source[22] - 48); uint num18 = (uint)(source[23] - 48); uint num19 = (uint)(source[24] - 48); uint num20 = (uint)(source[25] - 48); uint num21 = (uint)(source[26] - 48); if (num15 > 9 || num16 > 9 || num17 > 9 || num18 > 9 || num19 > 9 || num20 > 9 || num21 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int fraction = (int)(num15 * 1000000 + num16 * 100000 + num17 * 10000 + num18 * 1000 + num19 * 100 + num20 * 10 + num21); byte b = (byte)((source.Length > 27) ? source[27] : 0); if (b != 90 && b != 43 && b != 45) { if (!TryCreateDateTimeOffsetInterpretingDataAsLocalTime(year, month, day, hour, minute, second, fraction, out value)) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } bytesConsumed = 27; kind = DateTimeKind.Unspecified; return true; } if (b == 90) { if (!TryCreateDateTimeOffset(year, month, day, hour, minute, second, fraction, offsetNegative: false, 0, 0, out value)) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } bytesConsumed = 28; kind = DateTimeKind.Utc; return true; } if (source.Length < 33) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num22 = (uint)(source[28] - 48); uint num23 = (uint)(source[29] - 48); if (num22 > 9 || num23 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int offsetHours = (int)(num22 * 10 + num23); if (source[30] != 58) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } uint num24 = (uint)(source[31] - 48); uint num25 = (uint)(source[32] - 48); if (num24 > 9 || num25 > 9) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } int offsetMinutes = (int)(num24 * 10 + num25); if (!TryCreateDateTimeOffset(year, month, day, hour, minute, second, fraction, b == 45, offsetHours, offsetMinutes, out value)) { value = default(DateTimeOffset); bytesConsumed = 0; kind = DateTimeKind.Unspecified; return false; } bytesConsumed = 33; kind = DateTimeKind.Local; return true; } private static bool TryParseDateTimeOffsetR(ReadOnlySpan source, uint caseFlipXorMask, out DateTimeOffset dateTimeOffset, out int bytesConsumed) { if (source.Length < 29) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num = source[0] ^ caseFlipXorMask; uint num2 = source[1]; uint num3 = source[2]; uint num4 = source[3]; DayOfWeek dayOfWeek; switch ((num << 24) | (num2 << 16) | (num3 << 8) | num4) { case 1400204844u: dayOfWeek = DayOfWeek.Sunday; break; case 1299148332u: dayOfWeek = DayOfWeek.Monday; break; case 1416979756u: dayOfWeek = DayOfWeek.Tuesday; break; case 1466262572u: dayOfWeek = DayOfWeek.Wednesday; break; case 1416131884u: dayOfWeek = DayOfWeek.Thursday; break; case 1181903148u: dayOfWeek = DayOfWeek.Friday; break; case 1398895660u: dayOfWeek = DayOfWeek.Saturday; break; default: bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } if (source[4] != 32) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num5 = (uint)(source[5] - 48); uint num6 = (uint)(source[6] - 48); if (num5 > 9 || num6 > 9) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } int day = (int)(num5 * 10 + num6); if (source[7] != 32) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num7 = source[8] ^ caseFlipXorMask; uint num8 = source[9]; uint num9 = source[10]; uint num10 = source[11]; int month; switch ((num7 << 24) | (num8 << 16) | (num9 << 8) | num10) { case 1247899168u: month = 1; break; case 1181049376u: month = 2; break; case 1298231840u: month = 3; break; case 1097888288u: month = 4; break; case 1298233632u: month = 5; break; case 1249209888u: month = 6; break; case 1249209376u: month = 7; break; case 1098213152u: month = 8; break; case 1399156768u: month = 9; break; case 1331917856u: month = 10; break; case 1315927584u: month = 11; break; case 1147495200u: month = 12; break; default: bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num11 = (uint)(source[12] - 48); uint num12 = (uint)(source[13] - 48); uint num13 = (uint)(source[14] - 48); uint num14 = (uint)(source[15] - 48); if (num11 > 9 || num12 > 9 || num13 > 9 || num14 > 9) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } int year = (int)(num11 * 1000 + num12 * 100 + num13 * 10 + num14); if (source[16] != 32) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num15 = (uint)(source[17] - 48); uint num16 = (uint)(source[18] - 48); if (num15 > 9 || num16 > 9) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } int hour = (int)(num15 * 10 + num16); if (source[19] != 58) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num17 = (uint)(source[20] - 48); uint num18 = (uint)(source[21] - 48); if (num17 > 9 || num18 > 9) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } int minute = (int)(num17 * 10 + num18); if (source[22] != 58) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } uint num19 = (uint)(source[23] - 48); uint num20 = (uint)(source[24] - 48); if (num19 > 9 || num20 > 9) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } int second = (int)(num19 * 10 + num20); uint num21 = source[25]; uint num22 = source[26] ^ caseFlipXorMask; uint num23 = source[27] ^ caseFlipXorMask; uint num24 = source[28] ^ caseFlipXorMask; uint num25 = (num21 << 24) | (num22 << 16) | (num23 << 8) | num24; if (num25 != 541543764) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } if (!TryCreateDateTimeOffset(year, month, day, hour, minute, second, 0, offsetNegative: false, 0, 0, out dateTimeOffset)) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } if (dayOfWeek != dateTimeOffset.DayOfWeek) { bytesConsumed = 0; dateTimeOffset = default(DateTimeOffset); return false; } bytesConsumed = 29; return true; } public static bool TryParse(ReadOnlySpan source, out decimal value, out int bytesConsumed, char standardFormat = '\0') { ParseNumberOptions options; switch (standardFormat) { case '\0': case 'E': case 'G': case 'e': case 'g': options = ParseNumberOptions.AllowExponent; break; case 'F': case 'f': options = (ParseNumberOptions)0; break; default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } NumberBuffer number = default(NumberBuffer); if (!TryParseNumber(source, ref number, out bytesConsumed, options, out var textUsedExponentNotation)) { value = default(decimal); return false; } if (!textUsedExponentNotation && (standardFormat == 'E' || standardFormat == 'e')) { value = default(decimal); bytesConsumed = 0; return false; } if (number.Digits[0] == 0 && number.Scale == 0) { number.IsNegative = false; } value = default(decimal); if (!System.Number.NumberBufferToDecimal(ref number, ref value)) { value = default(decimal); bytesConsumed = 0; return false; } return true; } public static bool TryParse(ReadOnlySpan source, out float value, out int bytesConsumed, char standardFormat = '\0') { if (TryParseNormalAsFloatingPoint(source, out var value2, out bytesConsumed, standardFormat)) { value = (float)value2; if (float.IsInfinity(value)) { value = 0f; bytesConsumed = 0; return false; } return true; } return TryParseAsSpecialFloatingPoint(source, float.PositiveInfinity, float.NegativeInfinity, float.NaN, out value, out bytesConsumed); } public static bool TryParse(ReadOnlySpan source, out double value, out int bytesConsumed, char standardFormat = '\0') { if (TryParseNormalAsFloatingPoint(source, out value, out bytesConsumed, standardFormat)) { return true; } return TryParseAsSpecialFloatingPoint(source, double.PositiveInfinity, double.NegativeInfinity, double.NaN, out value, out bytesConsumed); } private static bool TryParseNormalAsFloatingPoint(ReadOnlySpan source, out double value, out int bytesConsumed, char standardFormat) { ParseNumberOptions options; switch (standardFormat) { case '\0': case 'E': case 'G': case 'e': case 'g': options = ParseNumberOptions.AllowExponent; break; case 'F': case 'f': options = (ParseNumberOptions)0; break; default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } NumberBuffer number = default(NumberBuffer); if (!TryParseNumber(source, ref number, out bytesConsumed, options, out var textUsedExponentNotation)) { value = 0.0; return false; } if (!textUsedExponentNotation && (standardFormat == 'E' || standardFormat == 'e')) { value = 0.0; bytesConsumed = 0; return false; } if (number.Digits[0] == 0) { number.IsNegative = false; } if (!System.Number.NumberBufferToDouble(ref number, out value)) { value = 0.0; bytesConsumed = 0; return false; } return true; } private static bool TryParseAsSpecialFloatingPoint(ReadOnlySpan source, T positiveInfinity, T negativeInfinity, T nan, out T value, out int bytesConsumed) { if (source.Length >= 8 && source[0] == 73 && source[1] == 110 && source[2] == 102 && source[3] == 105 && source[4] == 110 && source[5] == 105 && source[6] == 116 && source[7] == 121) { value = positiveInfinity; bytesConsumed = 8; return true; } if (source.Length >= 9 && source[0] == 45 && source[1] == 73 && source[2] == 110 && source[3] == 102 && source[4] == 105 && source[5] == 110 && source[6] == 105 && source[7] == 116 && source[8] == 121) { value = negativeInfinity; bytesConsumed = 9; return true; } if (source.Length >= 3 && source[0] == 78 && source[1] == 97 && source[2] == 78) { value = nan; bytesConsumed = 3; return true; } value = default(T); bytesConsumed = 0; return false; } public static bool TryParse(ReadOnlySpan source, out Guid value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': return TryParseGuidCore(source, ends: false, ' ', ' ', out value, out bytesConsumed); case 'B': return TryParseGuidCore(source, ends: true, '{', '}', out value, out bytesConsumed); case 'P': return TryParseGuidCore(source, ends: true, '(', ')', out value, out bytesConsumed); case 'N': return TryParseGuidN(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } private static bool TryParseGuidN(ReadOnlySpan text, out Guid value, out int bytesConsumed) { if (text.Length < 32) { value = default(Guid); bytesConsumed = 0; return false; } if (!TryParseUInt32X(text.Slice(0, 8), out var value2, out var bytesConsumed2) || bytesConsumed2 != 8) { value = default(Guid); bytesConsumed = 0; return false; } if (!TryParseUInt16X(text.Slice(8, 4), out var value3, out bytesConsumed2) || bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (!TryParseUInt16X(text.Slice(12, 4), out var value4, out bytesConsumed2) || bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (!TryParseUInt16X(text.Slice(16, 4), out var value5, out bytesConsumed2) || bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (!TryParseUInt64X(text.Slice(20), out var value6, out bytesConsumed2) || bytesConsumed2 != 12) { value = default(Guid); bytesConsumed = 0; return false; } bytesConsumed = 32; value = new Guid((int)value2, (short)value3, (short)value4, (byte)(value5 >> 8), (byte)value5, (byte)(value6 >> 40), (byte)(value6 >> 32), (byte)(value6 >> 24), (byte)(value6 >> 16), (byte)(value6 >> 8), (byte)value6); return true; } private static bool TryParseGuidCore(ReadOnlySpan source, bool ends, char begin, char end, out Guid value, out int bytesConsumed) { int num = 36 + (ends ? 2 : 0); if (source.Length < num) { value = default(Guid); bytesConsumed = 0; return false; } if (ends) { if (source[0] != begin) { value = default(Guid); bytesConsumed = 0; return false; } source = source.Slice(1); } if (!TryParseUInt32X(source, out var value2, out var bytesConsumed2)) { value = default(Guid); bytesConsumed = 0; return false; } if (bytesConsumed2 != 8) { value = default(Guid); bytesConsumed = 0; return false; } if (source[bytesConsumed2] != 45) { value = default(Guid); bytesConsumed = 0; return false; } source = source.Slice(9); if (!TryParseUInt16X(source, out var value3, out bytesConsumed2)) { value = default(Guid); bytesConsumed = 0; return false; } if (bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (source[bytesConsumed2] != 45) { value = default(Guid); bytesConsumed = 0; return false; } source = source.Slice(5); if (!TryParseUInt16X(source, out var value4, out bytesConsumed2)) { value = default(Guid); bytesConsumed = 0; return false; } if (bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (source[bytesConsumed2] != 45) { value = default(Guid); bytesConsumed = 0; return false; } source = source.Slice(5); if (!TryParseUInt16X(source, out var value5, out bytesConsumed2)) { value = default(Guid); bytesConsumed = 0; return false; } if (bytesConsumed2 != 4) { value = default(Guid); bytesConsumed = 0; return false; } if (source[bytesConsumed2] != 45) { value = default(Guid); bytesConsumed = 0; return false; } source = source.Slice(5); if (!TryParseUInt64X(source, out var value6, out bytesConsumed2)) { value = default(Guid); bytesConsumed = 0; return false; } if (bytesConsumed2 != 12) { value = default(Guid); bytesConsumed = 0; return false; } if (ends && source[bytesConsumed2] != end) { value = default(Guid); bytesConsumed = 0; return false; } bytesConsumed = num; value = new Guid((int)value2, (short)value3, (short)value4, (byte)(value5 >> 8), (byte)value5, (byte)(value6 >> 40), (byte)(value6 >> 32), (byte)(value6 >> 24), (byte)(value6 >> 16), (byte)(value6 >> 8), (byte)value6); return true; } [CLSCompliant(false)] public static bool TryParse(ReadOnlySpan source, out sbyte value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseSByteD(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseSByteN(source, out value, out bytesConsumed); case 'X': case 'x': value = 0; return TryParseByteX(source, out Unsafe.As(ref value), out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } public static bool TryParse(ReadOnlySpan source, out short value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseInt16D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseInt16N(source, out value, out bytesConsumed); case 'X': case 'x': value = 0; return TryParseUInt16X(source, out Unsafe.As(ref value), out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } public static bool TryParse(ReadOnlySpan source, out int value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseInt32D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseInt32N(source, out value, out bytesConsumed); case 'X': case 'x': value = 0; return TryParseUInt32X(source, out Unsafe.As(ref value), out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } public static bool TryParse(ReadOnlySpan source, out long value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseInt64D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseInt64N(source, out value, out bytesConsumed); case 'X': case 'x': value = 0L; return TryParseUInt64X(source, out Unsafe.As(ref value), out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } private static bool TryParseSByteD(ReadOnlySpan source, out sbyte value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0123; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0123; } num3 = source[num2]; } num4 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { if (num3 != 48) { goto IL_009c; } while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_0091; } goto IL_012b; } } goto IL_0123; IL_012b: bytesConsumed = num2; value = (sbyte)(num4 * num); return true; IL_009c: num4 = num3 - 48; num2++; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = num4 * 10 + num3 - 48; if ((uint)num4 > 127L + (long)((-1 * num + 1) / 2) || ((uint)num2 < (uint)source.Length && System.Buffers.Text.ParserHelpers.IsDigit(source[num2]))) { goto IL_0123; } } } } } goto IL_012b; IL_0123: bytesConsumed = 0; value = 0; return false; IL_0091: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_009c; } goto IL_012b; } private static bool TryParseInt16D(ReadOnlySpan source, out short value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0186; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0186; } num3 = source[num2]; } num4 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { if (num3 != 48) { goto IL_009c; } while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_0091; } goto IL_018e; } } goto IL_0186; IL_018e: bytesConsumed = num2; value = (short)(num4 * num); return true; IL_009c: num4 = num3 - 48; num2++; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = num4 * 10 + num3 - 48; if ((uint)num4 > 32767L + (long)((-1 * num + 1) / 2) || ((uint)num2 < (uint)source.Length && System.Buffers.Text.ParserHelpers.IsDigit(source[num2]))) { goto IL_0186; } } } } } } } } } goto IL_018e; IL_0186: bytesConsumed = 0; value = 0; return false; IL_0091: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_009c; } goto IL_018e; } private static bool TryParseInt32D(ReadOnlySpan source, out int value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0281; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0281; } num3 = source[num2]; } num4 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { if (num3 != 48) { goto IL_009c; } while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_0091; } goto IL_0289; } } goto IL_0281; IL_0289: bytesConsumed = num2; value = num4 * num; return true; IL_009c: num4 = num3 - 48; num2++; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; num4 = 10 * num4 + num3 - 48; if ((uint)num2 < (uint)source.Length) { num3 = source[num2]; if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num2++; if (num4 <= 214748364) { num4 = num4 * 10 + num3 - 48; if ((uint)num4 <= 2147483647L + (long)((-1 * num + 1) / 2) && ((uint)num2 >= (uint)source.Length || !System.Buffers.Text.ParserHelpers.IsDigit(source[num2]))) { goto IL_0289; } } goto IL_0281; } } } } } } } } } } } } } } } } } } goto IL_0289; IL_0281: bytesConsumed = 0; value = 0; return false; IL_0091: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_009c; } goto IL_0289; } private static bool TryParseInt64D(ReadOnlySpan source, out long value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0L; return false; } int num = 0; int num2 = 1; if (source[0] == 45) { num = 1; num2 = -1; if (source.Length <= num) { bytesConsumed = 0; value = 0L; return false; } } else if (source[0] == 43) { num = 1; if (source.Length <= num) { bytesConsumed = 0; value = 0L; return false; } } int num3 = 19 + num; long num4 = source[num] - 48; if (num4 < 0 || num4 > 9) { bytesConsumed = 0; value = 0L; return false; } ulong num5 = (ulong)num4; if (source.Length < num3) { for (int i = num + 1; i < source.Length; i++) { long num6 = source[i] - 48; if (num6 < 0 || num6 > 9) { bytesConsumed = i; value = (long)num5 * (long)num2; return true; } num5 = num5 * 10 + (ulong)num6; } } else { for (int j = num + 1; j < num3 - 1; j++) { long num7 = source[j] - 48; if (num7 < 0 || num7 > 9) { bytesConsumed = j; value = (long)num5 * (long)num2; return true; } num5 = num5 * 10 + (ulong)num7; } for (int k = num3 - 1; k < source.Length; k++) { long num8 = source[k] - 48; if (num8 < 0 || num8 > 9) { bytesConsumed = k; value = (long)num5 * (long)num2; return true; } bool flag = num2 > 0; bool flag2 = num8 > 8 || (flag && num8 > 7); if (num5 > 922337203685477580L || (num5 == 922337203685477580L && flag2)) { bytesConsumed = 0; value = 0L; return false; } num5 = num5 * 10 + (ulong)num8; } } bytesConsumed = source.Length; value = (long)num5 * (long)num2; return true; } private static bool TryParseSByteN(ReadOnlySpan source, out sbyte value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_00f9; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_00f9; } num3 = source[num2]; } if (num3 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num4 = num3 - 48; while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 44) { continue; } if (num3 == 46) { goto IL_00d4; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num3)) { break; } num4 = num4 * 10 + num3 - 48; if (num4 <= 127 + (-1 * num + 1) / 2) { continue; } goto IL_00f9; } goto IL_0101; } } else { num4 = 0; num2++; if ((uint)num2 < (uint)source.Length && source[num2] == 48) { goto IL_00d4; } } } goto IL_00f9; IL_00f9: bytesConsumed = 0; value = 0; return false; IL_00f1: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_00f9; } goto IL_0101; IL_00d4: while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_00f1; } goto IL_0101; IL_0101: bytesConsumed = num2; value = (sbyte)(num4 * num); return true; } private static bool TryParseInt16N(ReadOnlySpan source, out short value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_00ff; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_00ff; } num3 = source[num2]; } if (num3 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num4 = num3 - 48; while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 44) { continue; } if (num3 == 46) { goto IL_00da; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num3)) { break; } num4 = num4 * 10 + num3 - 48; if (num4 <= 32767 + (-1 * num + 1) / 2) { continue; } goto IL_00ff; } goto IL_0107; } } else { num4 = 0; num2++; if ((uint)num2 < (uint)source.Length && source[num2] == 48) { goto IL_00da; } } } goto IL_00ff; IL_00ff: bytesConsumed = 0; value = 0; return false; IL_00f7: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_00ff; } goto IL_0107; IL_00da: while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_00f7; } goto IL_0107; IL_0107: bytesConsumed = num2; value = (short)(num4 * num); return true; } private static bool TryParseInt32N(ReadOnlySpan source, out int value, out int bytesConsumed) { int num; int num2; int num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_010a; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_010a; } num3 = source[num2]; } if (num3 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num4 = num3 - 48; while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 44) { continue; } if (num3 == 46) { goto IL_00e5; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num3)) { break; } if ((uint)num4 <= 214748364u) { num4 = num4 * 10 + num3 - 48; if ((uint)num4 <= 2147483647L + (long)((-1 * num + 1) / 2)) { continue; } } goto IL_010a; } goto IL_0112; } } else { num4 = 0; num2++; if ((uint)num2 < (uint)source.Length && source[num2] == 48) { goto IL_00e5; } } } goto IL_010a; IL_010a: bytesConsumed = 0; value = 0; return false; IL_0102: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_010a; } goto IL_0112; IL_00e5: while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_0102; } goto IL_0112; IL_0112: bytesConsumed = num2; value = num4 * num; return true; } private static bool TryParseInt64N(ReadOnlySpan source, out long value, out int bytesConsumed) { int num; int num2; long num4; int num3; if (source.Length >= 1) { num = 1; num2 = 0; num3 = source[num2]; if (num3 == 45) { num = -1; num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0115; } num3 = source[num2]; } else if (num3 == 43) { num2++; if ((uint)num2 >= (uint)source.Length) { goto IL_0115; } num3 = source[num2]; } if (num3 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { num4 = num3 - 48; while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 44) { continue; } if (num3 == 46) { goto IL_00f0; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num3)) { break; } if ((ulong)num4 <= 922337203685477580uL) { num4 = num4 * 10 + num3 - 48; if ((ulong)num4 <= (ulong)(long.MaxValue + (-1 * num + 1) / 2)) { continue; } } goto IL_0115; } goto IL_011e; } } else { num4 = 0L; num2++; if ((uint)num2 < (uint)source.Length && source[num2] == 48) { goto IL_00f0; } } } goto IL_0115; IL_0115: bytesConsumed = 0; value = 0L; return false; IL_010d: if (System.Buffers.Text.ParserHelpers.IsDigit(num3)) { goto IL_0115; } goto IL_011e; IL_00f0: while (true) { num2++; if ((uint)num2 >= (uint)source.Length) { break; } num3 = source[num2]; if (num3 == 48) { continue; } goto IL_010d; } goto IL_011e; IL_011e: bytesConsumed = num2; value = num4 * num; return true; } public static bool TryParse(ReadOnlySpan source, out byte value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseByteD(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseByteN(source, out value, out bytesConsumed); case 'X': case 'x': return TryParseByteX(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } [CLSCompliant(false)] public static bool TryParse(ReadOnlySpan source, out ushort value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseUInt16D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseUInt16N(source, out value, out bytesConsumed); case 'X': case 'x': return TryParseUInt16X(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } [CLSCompliant(false)] public static bool TryParse(ReadOnlySpan source, out uint value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseUInt32D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseUInt32N(source, out value, out bytesConsumed); case 'X': case 'x': return TryParseUInt32X(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } [CLSCompliant(false)] public static bool TryParse(ReadOnlySpan source, out ulong value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'D': case 'G': case 'd': case 'g': return TryParseUInt64D(source, out value, out bytesConsumed); case 'N': case 'n': return TryParseUInt64N(source, out value, out bytesConsumed); case 'X': case 'x': return TryParseUInt64X(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } private static bool TryParseByteD(ReadOnlySpan source, out byte value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; num3 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { if (num2 != 48) { goto IL_0056; } while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_004b; } goto IL_00dd; } } goto IL_00d5; IL_004b: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_0056; } goto IL_00dd; IL_0056: num3 = num2 - 48; num++; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = num3 * 10 + num2 - 48; if ((uint)num3 > 255u || ((uint)num < (uint)source.Length && System.Buffers.Text.ParserHelpers.IsDigit(source[num]))) { goto IL_00d5; } } } } } goto IL_00dd; IL_00dd: bytesConsumed = num; value = (byte)num3; return true; IL_00d5: bytesConsumed = 0; value = 0; return false; } private static bool TryParseUInt16D(ReadOnlySpan source, out ushort value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; num3 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { if (num2 != 48) { goto IL_0056; } while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_004b; } goto IL_013d; } } goto IL_0135; IL_004b: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_0056; } goto IL_013d; IL_0056: num3 = num2 - 48; num++; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = num3 * 10 + num2 - 48; if ((uint)num3 > 65535u || ((uint)num < (uint)source.Length && System.Buffers.Text.ParserHelpers.IsDigit(source[num]))) { goto IL_0135; } } } } } } } } } goto IL_013d; IL_013d: bytesConsumed = num; value = (ushort)num3; return true; IL_0135: bytesConsumed = 0; value = 0; return false; } private static bool TryParseUInt32D(ReadOnlySpan source, out uint value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; num3 = 0; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { if (num2 != 48) { goto IL_0056; } while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_004b; } goto IL_023d; } } goto IL_0235; IL_004b: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_0056; } goto IL_023d; IL_0056: num3 = num2 - 48; num++; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; num3 = 10 * num3 + num2 - 48; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num++; if ((uint)num3 <= 429496729u && (num3 != 429496729 || num2 <= 53)) { num3 = num3 * 10 + num2 - 48; if ((uint)num >= (uint)source.Length || !System.Buffers.Text.ParserHelpers.IsDigit(source[num])) { goto IL_023d; } } goto IL_0235; } } } } } } } } } } } } } } } } } } goto IL_023d; IL_023d: bytesConsumed = num; value = (uint)num3; return true; IL_0235: bytesConsumed = 0; value = 0u; return false; } private static bool TryParseUInt64D(ReadOnlySpan source, out ulong value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0uL; return false; } ulong num = (uint)(source[0] - 48); if (num > 9) { bytesConsumed = 0; value = 0uL; return false; } ulong num2 = num; if (source.Length < 19) { for (int i = 1; i < source.Length; i++) { ulong num3 = (uint)(source[i] - 48); if (num3 > 9) { bytesConsumed = i; value = num2; return true; } num2 = num2 * 10 + num3; } } else { for (int j = 1; j < 18; j++) { ulong num4 = (uint)(source[j] - 48); if (num4 > 9) { bytesConsumed = j; value = num2; return true; } num2 = num2 * 10 + num4; } for (int k = 18; k < source.Length; k++) { ulong num5 = (uint)(source[k] - 48); if (num5 > 9) { bytesConsumed = k; value = num2; return true; } if (num2 > 1844674407370955161L || (num2 == 1844674407370955161L && num5 > 5)) { bytesConsumed = 0; value = 0uL; return false; } num2 = num2 * 10 + num5; } } bytesConsumed = source.Length; value = num2; return true; } private static bool TryParseByteN(ReadOnlySpan source, out byte value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; if (num2 == 43) { num++; if ((uint)num >= (uint)source.Length) { goto IL_00ce; } num2 = source[num]; } if (num2 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num3 = num2 - 48; while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 44) { continue; } if (num2 == 46) { goto IL_00a9; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num2)) { break; } num3 = num3 * 10 + num2 - 48; if (num3 <= 255) { continue; } goto IL_00ce; } goto IL_00d6; } } else { num3 = 0; num++; if ((uint)num < (uint)source.Length && source[num] == 48) { goto IL_00a9; } } } goto IL_00ce; IL_00c6: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_00ce; } goto IL_00d6; IL_00a9: while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_00c6; } goto IL_00d6; IL_00d6: bytesConsumed = num; value = (byte)num3; return true; IL_00ce: bytesConsumed = 0; value = 0; return false; } private static bool TryParseUInt16N(ReadOnlySpan source, out ushort value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; if (num2 == 43) { num++; if ((uint)num >= (uint)source.Length) { goto IL_00ce; } num2 = source[num]; } if (num2 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num3 = num2 - 48; while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 44) { continue; } if (num2 == 46) { goto IL_00a9; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num2)) { break; } num3 = num3 * 10 + num2 - 48; if (num3 <= 65535) { continue; } goto IL_00ce; } goto IL_00d6; } } else { num3 = 0; num++; if ((uint)num < (uint)source.Length && source[num] == 48) { goto IL_00a9; } } } goto IL_00ce; IL_00c6: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_00ce; } goto IL_00d6; IL_00a9: while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_00c6; } goto IL_00d6; IL_00d6: bytesConsumed = num; value = (ushort)num3; return true; IL_00ce: bytesConsumed = 0; value = 0; return false; } private static bool TryParseUInt32N(ReadOnlySpan source, out uint value, out int bytesConsumed) { int num; int num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; if (num2 == 43) { num++; if ((uint)num >= (uint)source.Length) { goto IL_00de; } num2 = source[num]; } if (num2 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num3 = num2 - 48; while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 44) { continue; } if (num2 == 46) { goto IL_00b9; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num2)) { break; } if ((uint)num3 <= 429496729u && (num3 != 429496729 || num2 <= 53)) { num3 = num3 * 10 + num2 - 48; continue; } goto IL_00de; } goto IL_00e6; } } else { num3 = 0; num++; if ((uint)num < (uint)source.Length && source[num] == 48) { goto IL_00b9; } } } goto IL_00de; IL_00de: bytesConsumed = 0; value = 0u; return false; IL_00b9: while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_00d6; } goto IL_00e6; IL_00e6: bytesConsumed = num; value = (uint)num3; return true; IL_00d6: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_00de; } goto IL_00e6; } private static bool TryParseUInt64N(ReadOnlySpan source, out ulong value, out int bytesConsumed) { int num; long num3; int num2; if (source.Length >= 1) { num = 0; num2 = source[num]; if (num2 == 43) { num++; if ((uint)num >= (uint)source.Length) { goto IL_00eb; } num2 = source[num]; } if (num2 != 46) { if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { num3 = num2 - 48; while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 44) { continue; } if (num2 == 46) { goto IL_00c6; } if (!System.Buffers.Text.ParserHelpers.IsDigit(num2)) { break; } if ((ulong)num3 <= 1844674407370955161uL && (num3 != 1844674407370955161L || num2 <= 53)) { num3 = num3 * 10 + num2 - 48; continue; } goto IL_00eb; } goto IL_00f4; } } else { num3 = 0L; num++; if ((uint)num < (uint)source.Length && source[num] == 48) { goto IL_00c6; } } } goto IL_00eb; IL_00eb: bytesConsumed = 0; value = 0uL; return false; IL_00c6: while (true) { num++; if ((uint)num >= (uint)source.Length) { break; } num2 = source[num]; if (num2 == 48) { continue; } goto IL_00e3; } goto IL_00f4; IL_00f4: bytesConsumed = num; value = (ulong)num3; return true; IL_00e3: if (System.Buffers.Text.ParserHelpers.IsDigit(num2)) { goto IL_00eb; } goto IL_00f4; } private static bool TryParseByteX(ReadOnlySpan source, out byte value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0; return false; } byte[] s_hexLookup = System.Buffers.Text.ParserHelpers.s_hexLookup; byte b = source[0]; byte b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = 0; value = 0; return false; } uint num = b2; if (source.Length <= 2) { for (int i = 1; i < source.Length; i++) { b = source[i]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = i; value = (byte)num; return true; } num = (num << 4) + b2; } } else { for (int j = 1; j < 2; j++) { b = source[j]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = j; value = (byte)num; return true; } num = (num << 4) + b2; } for (int k = 2; k < source.Length; k++) { b = source[k]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = k; value = (byte)num; return true; } if (num > 15) { bytesConsumed = 0; value = 0; return false; } num = (num << 4) + b2; } } bytesConsumed = source.Length; value = (byte)num; return true; } private static bool TryParseUInt16X(ReadOnlySpan source, out ushort value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0; return false; } byte[] s_hexLookup = System.Buffers.Text.ParserHelpers.s_hexLookup; byte b = source[0]; byte b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = 0; value = 0; return false; } uint num = b2; if (source.Length <= 4) { for (int i = 1; i < source.Length; i++) { b = source[i]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = i; value = (ushort)num; return true; } num = (num << 4) + b2; } } else { for (int j = 1; j < 4; j++) { b = source[j]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = j; value = (ushort)num; return true; } num = (num << 4) + b2; } for (int k = 4; k < source.Length; k++) { b = source[k]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = k; value = (ushort)num; return true; } if (num > 4095) { bytesConsumed = 0; value = 0; return false; } num = (num << 4) + b2; } } bytesConsumed = source.Length; value = (ushort)num; return true; } private static bool TryParseUInt32X(ReadOnlySpan source, out uint value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0u; return false; } byte[] s_hexLookup = System.Buffers.Text.ParserHelpers.s_hexLookup; byte b = source[0]; byte b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = 0; value = 0u; return false; } uint num = b2; if (source.Length <= 8) { for (int i = 1; i < source.Length; i++) { b = source[i]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = i; value = num; return true; } num = (num << 4) + b2; } } else { for (int j = 1; j < 8; j++) { b = source[j]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = j; value = num; return true; } num = (num << 4) + b2; } for (int k = 8; k < source.Length; k++) { b = source[k]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = k; value = num; return true; } if (num > 268435455) { bytesConsumed = 0; value = 0u; return false; } num = (num << 4) + b2; } } bytesConsumed = source.Length; value = num; return true; } private static bool TryParseUInt64X(ReadOnlySpan source, out ulong value, out int bytesConsumed) { if (source.Length < 1) { bytesConsumed = 0; value = 0uL; return false; } byte[] s_hexLookup = System.Buffers.Text.ParserHelpers.s_hexLookup; byte b = source[0]; byte b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = 0; value = 0uL; return false; } ulong num = b2; if (source.Length <= 16) { for (int i = 1; i < source.Length; i++) { b = source[i]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = i; value = num; return true; } num = (num << 4) + b2; } } else { for (int j = 1; j < 16; j++) { b = source[j]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = j; value = num; return true; } num = (num << 4) + b2; } for (int k = 16; k < source.Length; k++) { b = source[k]; b2 = s_hexLookup[b]; if (b2 == byte.MaxValue) { bytesConsumed = k; value = num; return true; } if (num > 1152921504606846975L) { bytesConsumed = 0; value = 0uL; return false; } num = (num << 4) + b2; } } bytesConsumed = source.Length; value = num; return true; } private static bool TryParseNumber(ReadOnlySpan source, ref NumberBuffer number, out int bytesConsumed, ParseNumberOptions options, out bool textUsedExponentNotation) { textUsedExponentNotation = false; if (source.Length == 0) { bytesConsumed = 0; return false; } Span digits = number.Digits; int i = 0; int num = 0; byte b = source[i]; if (b != 43) { if (b != 45) { goto IL_0055; } number.IsNegative = true; } i++; if (i == source.Length) { bytesConsumed = 0; return false; } b = source[i]; goto IL_0055; IL_0229: if (!TryParseUInt32D(source.Slice(i), out var value, out var bytesConsumed2)) { bytesConsumed = 0; return false; } i += bytesConsumed2; bool flag; if (flag) { if (number.Scale < int.MinValue + value) { number.Scale = int.MinValue; } else { number.Scale -= (int)value; } } else { if (number.Scale > 2147483647L - (long)value) { bytesConsumed = 0; return false; } number.Scale += (int)value; } bytesConsumed = i; return true; IL_0055: int num2 = i; for (; i != source.Length; i++) { b = source[i]; if (b != 48) { break; } } if (i == source.Length) { digits[0] = 0; number.Scale = 0; bytesConsumed = i; return true; } int num3 = i; for (; i != source.Length; i++) { b = source[i]; if ((uint)(b - 48) > 9u) { break; } } int num4 = i - num2; int num5 = i - num3; int num6 = Math.Min(num5, 50); source.Slice(num3, num6).CopyTo(digits); num = num6; number.Scale = num5; if (i == source.Length) { bytesConsumed = i; return true; } int num7 = 0; if (b == 46) { i++; int num8 = i; for (; i != source.Length; i++) { b = source[i]; if ((uint)(b - 48) > 9u) { break; } } num7 = i - num8; int j = num8; if (num == 0) { for (; j < i && source[j] == 48; j++) { number.Scale--; } } int num9 = Math.Min(i - j, 51 - num - 1); source.Slice(j, num9).CopyTo(digits.Slice(num)); num += num9; if (i == source.Length) { if (num4 == 0 && num7 == 0) { bytesConsumed = 0; return false; } bytesConsumed = i; return true; } } if (num4 == 0 && num7 == 0) { bytesConsumed = 0; return false; } if ((b & -33) != 69) { bytesConsumed = i; return true; } textUsedExponentNotation = true; i++; if ((options & ParseNumberOptions.AllowExponent) == 0) { bytesConsumed = 0; return false; } if (i == source.Length) { bytesConsumed = 0; return false; } flag = false; b = source[i]; if (b != 43) { if (b != 45) { goto IL_0229; } flag = true; } i++; if (i == source.Length) { bytesConsumed = 0; return false; } b = source[i]; goto IL_0229; } private static bool TryParseTimeSpanBigG(ReadOnlySpan source, out TimeSpan value, out int bytesConsumed) { int i = 0; byte b = 0; for (; i != source.Length; i++) { b = source[i]; if (b != 32 && b != 9) { break; } } if (i == source.Length) { value = default(TimeSpan); bytesConsumed = 0; return false; } bool isNegative = false; if (b == 45) { isNegative = true; i++; if (i == source.Length) { value = default(TimeSpan); bytesConsumed = 0; return false; } } if (!TryParseUInt32D(source.Slice(i), out var value2, out var bytesConsumed2)) { value = default(TimeSpan); bytesConsumed = 0; return false; } i += bytesConsumed2; if (i == source.Length || source[i++] != 58) { value = default(TimeSpan); bytesConsumed = 0; return false; } if (!TryParseUInt32D(source.Slice(i), out var value3, out bytesConsumed2)) { value = default(TimeSpan); bytesConsumed = 0; return false; } i += bytesConsumed2; if (i == source.Length || source[i++] != 58) { value = default(TimeSpan); bytesConsumed = 0; return false; } if (!TryParseUInt32D(source.Slice(i), out var value4, out bytesConsumed2)) { value = default(TimeSpan); bytesConsumed = 0; return false; } i += bytesConsumed2; if (i == source.Length || source[i++] != 58) { value = default(TimeSpan); bytesConsumed = 0; return false; } if (!TryParseUInt32D(source.Slice(i), out var value5, out bytesConsumed2)) { value = default(TimeSpan); bytesConsumed = 0; return false; } i += bytesConsumed2; if (i == source.Length || source[i++] != 46) { value = default(TimeSpan); bytesConsumed = 0; return false; } if (!TryParseTimeSpanFraction(source.Slice(i), out var value6, out bytesConsumed2)) { value = default(TimeSpan); bytesConsumed = 0; return false; } i += bytesConsumed2; if (!TryCreateTimeSpan(isNegative, value2, value3, value4, value5, value6, out value)) { value = default(TimeSpan); bytesConsumed = 0; return false; } if (i != source.Length && (source[i] == 46 || source[i] == 58)) { value = default(TimeSpan); bytesConsumed = 0; return false; } bytesConsumed = i; return true; } private static bool TryParseTimeSpanC(ReadOnlySpan source, out TimeSpan value, out int bytesConsumed) { TimeSpanSplitter timeSpanSplitter = default(TimeSpanSplitter); if (!timeSpanSplitter.TrySplitTimeSpan(source, periodUsedToSeparateDay: true, out bytesConsumed)) { value = default(TimeSpan); return false; } bool isNegative = timeSpanSplitter.IsNegative; bool flag; switch (timeSpanSplitter.Separators) { case 0u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, 0u, 0u, 0u, 0u, out value); break; case 16777216u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, 0u, 0u, out value); break; case 33619968u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, 0u, 0u, out value); break; case 16842752u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, 0u, out value); break; case 33620224u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, 0u, out value); break; case 16843264u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, out value); break; case 33620226u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, timeSpanSplitter.V5, out value); break; default: value = default(TimeSpan); flag = false; break; } if (!flag) { bytesConsumed = 0; return false; } return true; } public static bool TryParse(ReadOnlySpan source, out TimeSpan value, out int bytesConsumed, char standardFormat = '\0') { switch (standardFormat) { case '\0': case 'T': case 'c': case 't': return TryParseTimeSpanC(source, out value, out bytesConsumed); case 'G': return TryParseTimeSpanBigG(source, out value, out bytesConsumed); case 'g': return TryParseTimeSpanLittleG(source, out value, out bytesConsumed); default: return System.ThrowHelper.TryParseThrowFormatException(out value, out bytesConsumed); } } private static bool TryParseTimeSpanFraction(ReadOnlySpan source, out uint value, out int bytesConsumed) { int num = 0; if (num == source.Length) { value = 0u; bytesConsumed = 0; return false; } uint num2 = (uint)(source[num] - 48); if (num2 > 9) { value = 0u; bytesConsumed = 0; return false; } num++; uint num3 = num2; int num4 = 1; while (num != source.Length) { num2 = (uint)(source[num] - 48); if (num2 > 9) { break; } num++; num4++; if (num4 > 7) { value = 0u; bytesConsumed = 0; return false; } num3 = 10 * num3 + num2; } switch (num4) { case 6: num3 *= 10; break; case 5: num3 *= 100; break; case 4: num3 *= 1000; break; case 3: num3 *= 10000; break; case 2: num3 *= 100000; break; default: num3 *= 1000000; break; case 7: break; } value = num3; bytesConsumed = num; return true; } private static bool TryCreateTimeSpan(bool isNegative, uint days, uint hours, uint minutes, uint seconds, uint fraction, out TimeSpan timeSpan) { if (hours > 23 || minutes > 59 || seconds > 59) { timeSpan = default(TimeSpan); return false; } long num = ((long)days * 3600L * 24 + (long)hours * 3600L + (long)minutes * 60L + seconds) * 1000; long ticks; if (isNegative) { num = -num; if (num < -922337203685477L) { timeSpan = default(TimeSpan); return false; } long num2 = num * 10000; if (num2 < long.MinValue + fraction) { timeSpan = default(TimeSpan); return false; } ticks = num2 - fraction; } else { if (num > 922337203685477L) { timeSpan = default(TimeSpan); return false; } long num3 = num * 10000; if (num3 > long.MaxValue - (long)fraction) { timeSpan = default(TimeSpan); return false; } ticks = num3 + fraction; } timeSpan = new TimeSpan(ticks); return true; } private static bool TryParseTimeSpanLittleG(ReadOnlySpan source, out TimeSpan value, out int bytesConsumed) { TimeSpanSplitter timeSpanSplitter = default(TimeSpanSplitter); if (!timeSpanSplitter.TrySplitTimeSpan(source, periodUsedToSeparateDay: false, out bytesConsumed)) { value = default(TimeSpan); return false; } bool isNegative = timeSpanSplitter.IsNegative; bool flag; switch (timeSpanSplitter.Separators) { case 0u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, 0u, 0u, 0u, 0u, out value); break; case 16777216u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, 0u, 0u, out value); break; case 16842752u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, 0u, out value); break; case 16843008u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, 0u, out value); break; case 16843264u: flag = TryCreateTimeSpan(isNegative, 0u, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, out value); break; case 16843010u: flag = TryCreateTimeSpan(isNegative, timeSpanSplitter.V1, timeSpanSplitter.V2, timeSpanSplitter.V3, timeSpanSplitter.V4, timeSpanSplitter.V5, out value); break; default: value = default(TimeSpan); flag = false; break; } if (!flag) { bytesConsumed = 0; return false; } return true; } } } namespace System.Buffers.Binary { internal static class BinaryPrimitives { [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static sbyte ReverseEndianness(sbyte value) { return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short ReverseEndianness(short value) { return (short)(((value & 0xFF) << 8) | ((value & 0xFF00) >> 8)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ReverseEndianness(int value) { return (int)ReverseEndianness((uint)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long ReverseEndianness(long value) { return (long)ReverseEndianness((ulong)value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte ReverseEndianness(byte value) { return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ushort ReverseEndianness(ushort value) { return (ushort)((value >> 8) + (value << 8)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static uint ReverseEndianness(uint value) { uint num = value & 0xFF00FF; uint num2 = value & 0xFF00FF00u; return ((num >> 8) | (num << 24)) + ((num2 << 8) | (num2 >> 24)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ulong ReverseEndianness(ulong value) { return ((ulong)ReverseEndianness((uint)value) << 32) + ReverseEndianness((uint)(value >> 32)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short ReadInt16BigEndian(ReadOnlySpan source) { short num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ReadInt32BigEndian(ReadOnlySpan source) { int num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long ReadInt64BigEndian(ReadOnlySpan source) { long num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ushort ReadUInt16BigEndian(ReadOnlySpan source) { ushort num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static uint ReadUInt32BigEndian(ReadOnlySpan source) { uint num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ulong ReadUInt64BigEndian(ReadOnlySpan source) { ulong num = MemoryMarshal.Read(source); if (BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt16BigEndian(ReadOnlySpan source, out short value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt32BigEndian(ReadOnlySpan source, out int value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt64BigEndian(ReadOnlySpan source, out long value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt16BigEndian(ReadOnlySpan source, out ushort value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt32BigEndian(ReadOnlySpan source, out uint value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt64BigEndian(ReadOnlySpan source, out ulong value) { bool result = MemoryMarshal.TryRead(source, out value); if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short ReadInt16LittleEndian(ReadOnlySpan source) { short num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int ReadInt32LittleEndian(ReadOnlySpan source) { int num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long ReadInt64LittleEndian(ReadOnlySpan source) { long num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ushort ReadUInt16LittleEndian(ReadOnlySpan source) { ushort num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static uint ReadUInt32LittleEndian(ReadOnlySpan source) { uint num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static ulong ReadUInt64LittleEndian(ReadOnlySpan source) { ulong num = MemoryMarshal.Read(source); if (!BitConverter.IsLittleEndian) { num = ReverseEndianness(num); } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt16LittleEndian(ReadOnlySpan source, out short value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt32LittleEndian(ReadOnlySpan source, out int value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryReadInt64LittleEndian(ReadOnlySpan source, out long value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt16LittleEndian(ReadOnlySpan source, out ushort value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt32LittleEndian(ReadOnlySpan source, out uint value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryReadUInt64LittleEndian(ReadOnlySpan source, out ulong value) { bool result = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt16BigEndian(Span destination, short value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt32BigEndian(Span destination, int value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt64BigEndian(Span destination, long value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt16BigEndian(Span destination, ushort value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt32BigEndian(Span destination, uint value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt64BigEndian(Span destination, ulong value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt16BigEndian(Span destination, short value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt32BigEndian(Span destination, int value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt64BigEndian(Span destination, long value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt16BigEndian(Span destination, ushort value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt32BigEndian(Span destination, uint value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt64BigEndian(Span destination, ulong value) { if (BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt16LittleEndian(Span destination, short value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt32LittleEndian(Span destination, int value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteInt64LittleEndian(Span destination, long value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt16LittleEndian(Span destination, ushort value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt32LittleEndian(Span destination, uint value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static void WriteUInt64LittleEndian(Span destination, ulong value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } MemoryMarshal.Write(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt16LittleEndian(Span destination, short value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt32LittleEndian(Span destination, int value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteInt64LittleEndian(Span destination, long value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt16LittleEndian(Span destination, ushort value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt32LittleEndian(Span destination, uint value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static bool TryWriteUInt64LittleEndian(Span destination, ulong value) { if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return MemoryMarshal.TryWrite(destination, ref value); } } } namespace FxResources.System.Numerics.Vectors { internal static class SR { } } namespace System { internal static class MathF { public const float PI = 3.1415927f; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Abs(float x) { return Math.Abs(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Acos(float x) { return (float)Math.Acos(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Cos(float x) { return (float)Math.Cos(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float IEEERemainder(float x, float y) { return (float)Math.IEEERemainder(x, y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Pow(float x, float y) { return (float)Math.Pow(x, y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Sin(float x) { return (float)Math.Sin(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Sqrt(float x) { return (float)Math.Sqrt(x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Tan(float x) { return (float)Math.Tan(x); } } internal static class SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(FxResources.System.Numerics.Vectors.SR))); internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException"); internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination"); internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef"); internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported"); internal static string Arg_InsufficientNumberOfElements => GetResourceString("Arg_InsufficientNumberOfElements"); private static bool UsingResourceKeys() { return s_usingResourceKeys; } internal static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } internal static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } 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; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, Inherited = false)] internal sealed class IntrinsicAttribute : Attribute { } } namespace System.Numerics { internal class ConstantHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte GetByteWithAllBitsSet() { byte result = 0; result = byte.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte GetSByteWithAllBitsSet() { sbyte result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort GetUInt16WithAllBitsSet() { ushort result = 0; result = ushort.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short GetInt16WithAllBitsSet() { short result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint GetUInt32WithAllBitsSet() { uint result = 0u; result = uint.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetInt32WithAllBitsSet() { int result = 0; result = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong GetUInt64WithAllBitsSet() { ulong result = 0uL; result = ulong.MaxValue; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetInt64WithAllBitsSet() { long result = 0L; result = -1L; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static float GetSingleWithAllBitsSet() { float result = 0f; *(int*)(&result) = -1; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static double GetDoubleWithAllBitsSet() { double result = 0.0; *(long*)(&result) = -1L; return result; } } [StructLayout(LayoutKind.Explicit)] internal struct Register { [FieldOffset(0)] internal byte byte_0; [FieldOffset(1)] internal byte byte_1; [FieldOffset(2)] internal byte byte_2; [FieldOffset(3)] internal byte byte_3; [FieldOffset(4)] internal byte byte_4; [FieldOffset(5)] internal byte byte_5; [FieldOffset(6)] internal byte byte_6; [FieldOffset(7)] internal byte byte_7; [FieldOffset(8)] internal byte byte_8; [FieldOffset(9)] internal byte byte_9; [FieldOffset(10)] internal byte byte_10; [FieldOffset(11)] internal byte byte_11; [FieldOffset(12)] internal byte byte_12; [FieldOffset(13)] internal byte byte_13; [FieldOffset(14)] internal byte byte_14; [FieldOffset(15)] internal byte byte_15; [FieldOffset(0)] internal sbyte sbyte_0; [FieldOffset(1)] internal sbyte sbyte_1; [FieldOffset(2)] internal sbyte sbyte_2; [FieldOffset(3)] internal sbyte sbyte_3; [FieldOffset(4)] internal sbyte sbyte_4; [FieldOffset(5)] internal sbyte sbyte_5; [FieldOffset(6)] internal sbyte sbyte_6; [FieldOffset(7)] internal sbyte sbyte_7; [FieldOffset(8)] internal sbyte sbyte_8; [FieldOffset(9)] internal sbyte sbyte_9; [FieldOffset(10)] internal sbyte sbyte_10; [FieldOffset(11)] internal sbyte sbyte_11; [FieldOffset(12)] internal sbyte sbyte_12; [FieldOffset(13)] internal sbyte sbyte_13; [FieldOffset(14)] internal sbyte sbyte_14; [FieldOffset(15)] internal sbyte sbyte_15; [FieldOffset(0)] internal ushort uint16_0; [FieldOffset(2)] internal ushort uint16_1; [FieldOffset(4)] internal ushort uint16_2; [FieldOffset(6)] internal ushort uint16_3; [FieldOffset(8)] internal ushort uint16_4; [FieldOffset(10)] internal ushort uint16_5; [FieldOffset(12)] internal ushort uint16_6; [FieldOffset(14)] internal ushort uint16_7; [FieldOffset(0)] internal short int16_0; [FieldOffset(2)] internal short int16_1; [FieldOffset(4)] internal short int16_2; [FieldOffset(6)] internal short int16_3; [FieldOffset(8)] internal short int16_4; [FieldOffset(10)] internal short int16_5; [FieldOffset(12)] internal short int16_6; [FieldOffset(14)] internal short int16_7; [FieldOffset(0)] internal uint uint32_0; [FieldOffset(4)] internal uint uint32_1; [FieldOffset(8)] internal uint uint32_2; [FieldOffset(12)] internal uint uint32_3; [FieldOffset(0)] internal int int32_0; [FieldOffset(4)] internal int int32_1; [FieldOffset(8)] internal int int32_2; [FieldOffset(12)] internal int int32_3; [FieldOffset(0)] internal ulong uint64_0; [FieldOffset(8)] internal ulong uint64_1; [FieldOffset(0)] internal long int64_0; [FieldOffset(8)] internal long int64_1; [FieldOffset(0)] internal float single_0; [FieldOffset(4)] internal float single_1; [FieldOffset(8)] internal float single_2; [FieldOffset(12)] internal float single_3; [FieldOffset(0)] internal double double_0; [FieldOffset(8)] internal double double_1; } [System.Runtime.CompilerServices.Intrinsic] internal struct Vector : IEquatable>, IFormattable where T : struct { private struct VectorSizeHelper { internal Vector _placeholder; internal byte _byte; } private Register register; private static readonly int s_count = InitializeCount(); private static readonly Vector s_zero = default(Vector); private static readonly Vector s_one = new Vector(GetOneValue()); private static readonly Vector s_allOnes = new Vector(GetAllBitsSetValue()); public static int Count { [System.Runtime.CompilerServices.Intrinsic] get { return s_count; } } public static Vector Zero { [System.Runtime.CompilerServices.Intrinsic] get { return s_zero; } } public static Vector One { [System.Runtime.CompilerServices.Intrinsic] get { return s_one; } } internal static Vector AllOnes => s_allOnes; public unsafe T this[int index] { [System.Runtime.CompilerServices.Intrinsic] get { if (index >= Count || index < 0) { throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index)); } if (typeof(T) == typeof(byte)) { fixed (byte* byte_ = ®ister.byte_0) { return (T)(object)byte_[index]; } } if (typeof(T) == typeof(sbyte)) { fixed (sbyte* sbyte_ = ®ister.sbyte_0) { return (T)(object)sbyte_[index]; } } if (typeof(T) == typeof(ushort)) { fixed (ushort* uint16_ = ®ister.uint16_0) { return (T)(object)uint16_[index]; } } if (typeof(T) == typeof(short)) { fixed (short* int16_ = ®ister.int16_0) { return (T)(object)int16_[index]; } } if (typeof(T) == typeof(uint)) { fixed (uint* uint32_ = ®ister.uint32_0) { return (T)(object)uint32_[index]; } } if (typeof(T) == typeof(int)) { fixed (int* int32_ = ®ister.int32_0) { return (T)(object)int32_[index]; } } if (typeof(T) == typeof(ulong)) { fixed (ulong* uint64_ = ®ister.uint64_0) { return (T)(object)uint64_[index]; } } if (typeof(T) == typeof(long)) { fixed (long* int64_ = ®ister.int64_0) { return (T)(object)int64_[index]; } } if (typeof(T) == typeof(float)) { fixed (float* single_ = ®ister.single_0) { return (T)(object)single_[index]; } } if (typeof(T) == typeof(double)) { fixed (double* double_ = ®ister.double_0) { return (T)(object)double_[index]; } } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } } private unsafe static int InitializeCount() { VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper); byte* ptr = &vectorSizeHelper._placeholder.register.byte_0; byte* ptr2 = &vectorSizeHelper._byte; int num = (int)(ptr2 - ptr); int num2 = -1; if (typeof(T) == typeof(byte)) { num2 = 1; } else if (typeof(T) == typeof(sbyte)) { num2 = 1; } else if (typeof(T) == typeof(ushort)) { num2 = 2; } else if (typeof(T) == typeof(short)) { num2 = 2; } else if (typeof(T) == typeof(uint)) { num2 = 4; } else if (typeof(T) == typeof(int)) { num2 = 4; } else if (typeof(T) == typeof(ulong)) { num2 = 8; } else if (typeof(T) == typeof(long)) { num2 = 8; } else if (typeof(T) == typeof(float)) { num2 = 4; } else { if (!(typeof(T) == typeof(double))) { throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } num2 = 8; } return num / num2; } [System.Runtime.CompilerServices.Intrinsic] public unsafe Vector(T value) { this = default(Vector); if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* byte_ = ®ister.byte_0) { for (int i = 0; i < Count; i++) { byte_[i] = (byte)(object)value; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* sbyte_ = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { sbyte_[j] = (sbyte)(object)value; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* uint16_ = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { uint16_[k] = (ushort)(object)value; } } } else if (typeof(T) == typeof(short)) { fixed (short* int16_ = ®ister.int16_0) { for (int l = 0; l < Count; l++) { int16_[l] = (short)(object)value; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* uint32_ = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { uint32_[m] = (uint)(object)value; } } } else if (typeof(T) == typeof(int)) { fixed (int* int32_ = ®ister.int32_0) { for (int n = 0; n < Count; n++) { int32_[n] = (int)(object)value; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* uint64_ = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { uint64_[num] = (ulong)(object)value; } } } else if (typeof(T) == typeof(long)) { fixed (long* int64_ = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { int64_[num2] = (long)(object)value; } } } else if (typeof(T) == typeof(float)) { fixed (float* single_ = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { single_[num3] = (float)(object)value; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* double_ = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { double_[num4] = (double)(object)value; } } } } else if (typeof(T) == typeof(byte)) { register.byte_0 = (byte)(object)value; register.byte_1 = (byte)(object)value; register.byte_2 = (byte)(object)value; register.byte_3 = (byte)(object)value; register.byte_4 = (byte)(object)value; register.byte_5 = (byte)(object)value; register.byte_6 = (byte)(object)value; register.byte_7 = (byte)(object)value; register.byte_8 = (byte)(object)value; register.byte_9 = (byte)(object)value; register.byte_10 = (byte)(object)value; register.byte_11 = (byte)(object)value; register.byte_12 = (byte)(object)value; register.byte_13 = (byte)(object)value; register.byte_14 = (byte)(object)value; register.byte_15 = (byte)(object)value; } else if (typeof(T) == typeof(sbyte)) { register.sbyte_0 = (sbyte)(object)value; register.sbyte_1 = (sbyte)(object)value; register.sbyte_2 = (sbyte)(object)value; register.sbyte_3 = (sbyte)(object)value; register.sbyte_4 = (sbyte)(object)value; register.sbyte_5 = (sbyte)(object)value; register.sbyte_6 = (sbyte)(object)value; register.sbyte_7 = (sbyte)(object)value; register.sbyte_8 = (sbyte)(object)value; register.sbyte_9 = (sbyte)(object)value; register.sbyte_10 = (sbyte)(object)value; register.sbyte_11 = (sbyte)(object)value; register.sbyte_12 = (sbyte)(object)value; register.sbyte_13 = (sbyte)(object)value; register.sbyte_14 = (sbyte)(object)value; register.sbyte_15 = (sbyte)(object)value; } else if (typeof(T) == typeof(ushort)) { register.uint16_0 = (ushort)(object)value; register.uint16_1 = (ushort)(object)value; register.uint16_2 = (ushort)(object)value; register.uint16_3 = (ushort)(object)value; register.uint16_4 = (ushort)(object)value; register.uint16_5 = (ushort)(object)value; register.uint16_6 = (ushort)(object)value; register.uint16_7 = (ushort)(object)value; } else if (typeof(T) == typeof(short)) { register.int16_0 = (short)(object)value; register.int16_1 = (short)(object)value; register.int16_2 = (short)(object)value; register.int16_3 = (short)(object)value; register.int16_4 = (short)(object)value; register.int16_5 = (short)(object)value; register.int16_6 = (short)(object)value; register.int16_7 = (short)(object)value; } else if (typeof(T) == typeof(uint)) { register.uint32_0 = (uint)(object)value; register.uint32_1 = (uint)(object)value; register.uint32_2 = (uint)(object)value; register.uint32_3 = (uint)(object)value; } else if (typeof(T) == typeof(int)) { register.int32_0 = (int)(object)value; register.int32_1 = (int)(object)value; register.int32_2 = (int)(object)value; register.int32_3 = (int)(object)value; } else if (typeof(T) == typeof(ulong)) { register.uint64_0 = (ulong)(object)value; register.uint64_1 = (ulong)(object)value; } else if (typeof(T) == typeof(long)) { register.int64_0 = (long)(object)value; register.int64_1 = (long)(object)value; } else if (typeof(T) == typeof(float)) { register.single_0 = (float)(object)value; register.single_1 = (float)(object)value; register.single_2 = (float)(object)value; register.single_3 = (float)(object)value; } else if (typeof(T) == typeof(double)) { register.double_0 = (double)(object)value; register.double_1 = (double)(object)value; } } [System.Runtime.CompilerServices.Intrinsic] public Vector(T[] values) : this(values, 0) { } public unsafe Vector(T[] values, int index) { this = default(Vector); if (values == null) { throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef); } if (index < 0 || values.Length - index < Count) { throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_InsufficientNumberOfElements, Count, "values")); } if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* byte_ = ®ister.byte_0) { for (int i = 0; i < Count; i++) { byte_[i] = (byte)(object)values[i + index]; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* sbyte_ = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { sbyte_[j] = (sbyte)(object)values[j + index]; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* uint16_ = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { uint16_[k] = (ushort)(object)values[k + index]; } } } else if (typeof(T) == typeof(short)) { fixed (short* int16_ = ®ister.int16_0) { for (int l = 0; l < Count; l++) { int16_[l] = (short)(object)values[l + index]; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* uint32_ = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { uint32_[m] = (uint)(object)values[m + index]; } } } else if (typeof(T) == typeof(int)) { fixed (int* int32_ = ®ister.int32_0) { for (int n = 0; n < Count; n++) { int32_[n] = (int)(object)values[n + index]; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* uint64_ = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { uint64_[num] = (ulong)(object)values[num + index]; } } } else if (typeof(T) == typeof(long)) { fixed (long* int64_ = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { int64_[num2] = (long)(object)values[num2 + index]; } } } else if (typeof(T) == typeof(float)) { fixed (float* single_ = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { single_[num3] = (float)(object)values[num3 + index]; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* double_ = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { double_[num4] = (double)(object)values[num4 + index]; } } } } else if (typeof(T) == typeof(byte)) { fixed (byte* byte_2 = ®ister.byte_0) { *byte_2 = (byte)(object)values[index]; byte_2[1] = (byte)(object)values[1 + index]; byte_2[2] = (byte)(object)values[2 + index]; byte_2[3] = (byte)(object)values[3 + index]; byte_2[4] = (byte)(object)values[4 + index]; byte_2[5] = (byte)(object)values[5 + index]; byte_2[6] = (byte)(object)values[6 + index]; byte_2[7] = (byte)(object)values[7 + index]; byte_2[8] = (byte)(object)values[8 + index]; byte_2[9] = (byte)(object)values[9 + index]; byte_2[10] = (byte)(object)values[10 + index]; byte_2[11] = (byte)(object)values[11 + index]; byte_2[12] = (byte)(object)values[12 + index]; byte_2[13] = (byte)(object)values[13 + index]; byte_2[14] = (byte)(object)values[14 + index]; byte_2[15] = (byte)(object)values[15 + index]; } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* sbyte_2 = ®ister.sbyte_0) { *sbyte_2 = (sbyte)(object)values[index]; sbyte_2[1] = (sbyte)(object)values[1 + index]; sbyte_2[2] = (sbyte)(object)values[2 + index]; sbyte_2[3] = (sbyte)(object)values[3 + index]; sbyte_2[4] = (sbyte)(object)values[4 + index]; sbyte_2[5] = (sbyte)(object)values[5 + index]; sbyte_2[6] = (sbyte)(object)values[6 + index]; sbyte_2[7] = (sbyte)(object)values[7 + index]; sbyte_2[8] = (sbyte)(object)values[8 + index]; sbyte_2[9] = (sbyte)(object)values[9 + index]; sbyte_2[10] = (sbyte)(object)values[10 + index]; sbyte_2[11] = (sbyte)(object)values[11 + index]; sbyte_2[12] = (sbyte)(object)values[12 + index]; sbyte_2[13] = (sbyte)(object)values[13 + index]; sbyte_2[14] = (sbyte)(object)values[14 + index]; sbyte_2[15] = (sbyte)(object)values[15 + index]; } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* uint16_2 = ®ister.uint16_0) { *uint16_2 = (ushort)(object)values[index]; uint16_2[1] = (ushort)(object)values[1 + index]; uint16_2[2] = (ushort)(object)values[2 + index]; uint16_2[3] = (ushort)(object)values[3 + index]; uint16_2[4] = (ushort)(object)values[4 + index]; uint16_2[5] = (ushort)(object)values[5 + index]; uint16_2[6] = (ushort)(object)values[6 + index]; uint16_2[7] = (ushort)(object)values[7 + index]; } } else if (typeof(T) == typeof(short)) { fixed (short* int16_2 = ®ister.int16_0) { *int16_2 = (short)(object)values[index]; int16_2[1] = (short)(object)values[1 + index]; int16_2[2] = (short)(object)values[2 + index]; int16_2[3] = (short)(object)values[3 + index]; int16_2[4] = (short)(object)values[4 + index]; int16_2[5] = (short)(object)values[5 + index]; int16_2[6] = (short)(object)values[6 + index]; int16_2[7] = (short)(object)values[7 + index]; } } else if (typeof(T) == typeof(uint)) { fixed (uint* uint32_2 = ®ister.uint32_0) { *uint32_2 = (uint)(object)values[index]; uint32_2[1] = (uint)(object)values[1 + index]; uint32_2[2] = (uint)(object)values[2 + index]; uint32_2[3] = (uint)(object)values[3 + index]; } } else if (typeof(T) == typeof(int)) { fixed (int* int32_2 = ®ister.int32_0) { *int32_2 = (int)(object)values[index]; int32_2[1] = (int)(object)values[1 + index]; int32_2[2] = (int)(object)values[2 + index]; int32_2[3] = (int)(object)values[3 + index]; } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* uint64_2 = ®ister.uint64_0) { *uint64_2 = (ulong)(object)values[index]; uint64_2[1] = (ulong)(object)values[1 + index]; } } else if (typeof(T) == typeof(long)) { fixed (long* int64_2 = ®ister.int64_0) { *int64_2 = (long)(object)values[index]; int64_2[1] = (long)(object)values[1 + index]; } } else if (typeof(T) == typeof(float)) { fixed (float* single_2 = ®ister.single_0) { *single_2 = (float)(object)values[index]; single_2[1] = (float)(object)values[1 + index]; single_2[2] = (float)(object)values[2 + index]; single_2[3] = (float)(object)values[3 + index]; } } else if (typeof(T) == typeof(double)) { fixed (double* double_2 = ®ister.double_0) { *double_2 = (double)(object)values[index]; double_2[1] = (double)(object)values[1 + index]; } } } internal unsafe Vector(void* dataPointer) : this(dataPointer, 0) { } internal unsafe Vector(void* dataPointer, int offset) { this = default(Vector); if (typeof(T) == typeof(byte)) { byte* ptr = (byte*)dataPointer; ptr += offset; fixed (byte* byte_ = ®ister.byte_0) { for (int i = 0; i < Count; i++) { byte_[i] = ptr[i]; } } return; } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = (sbyte*)dataPointer; ptr2 += offset; fixed (sbyte* sbyte_ = ®ister.sbyte_0) { for (int j = 0; j < Count; j++) { sbyte_[j] = ptr2[j]; } } return; } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = (ushort*)dataPointer; ptr3 += offset; fixed (ushort* uint16_ = ®ister.uint16_0) { for (int k = 0; k < Count; k++) { uint16_[k] = ptr3[k]; } } return; } if (typeof(T) == typeof(short)) { short* ptr4 = (short*)dataPointer; ptr4 += offset; fixed (short* int16_ = ®ister.int16_0) { for (int l = 0; l < Count; l++) { int16_[l] = ptr4[l]; } } return; } if (typeof(T) == typeof(uint)) { uint* ptr5 = (uint*)dataPointer; ptr5 += offset; fixed (uint* uint32_ = ®ister.uint32_0) { for (int m = 0; m < Count; m++) { uint32_[m] = ptr5[m]; } } return; } if (typeof(T) == typeof(int)) { int* ptr6 = (int*)dataPointer; ptr6 += offset; fixed (int* int32_ = ®ister.int32_0) { for (int n = 0; n < Count; n++) { int32_[n] = ptr6[n]; } } return; } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = (ulong*)dataPointer; ptr7 += offset; fixed (ulong* uint64_ = ®ister.uint64_0) { for (int num = 0; num < Count; num++) { uint64_[num] = ptr7[num]; } } return; } if (typeof(T) == typeof(long)) { long* ptr8 = (long*)dataPointer; ptr8 += offset; fixed (long* int64_ = ®ister.int64_0) { for (int num2 = 0; num2 < Count; num2++) { int64_[num2] = ptr8[num2]; } } return; } if (typeof(T) == typeof(float)) { float* ptr9 = (float*)dataPointer; ptr9 += offset; fixed (float* single_ = ®ister.single_0) { for (int num3 = 0; num3 < Count; num3++) { single_[num3] = ptr9[num3]; } } return; } if (typeof(T) == typeof(double)) { double* ptr10 = (double*)dataPointer; ptr10 += offset; fixed (double* double_ = ®ister.double_0) { for (int num4 = 0; num4 < Count; num4++) { double_[num4] = ptr10[num4]; } } return; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } private Vector(ref Register existingRegister) { register = existingRegister; } [System.Runtime.CompilerServices.Intrinsic] public void CopyTo(T[] destination) { CopyTo(destination, 0); } [System.Runtime.CompilerServices.Intrinsic] public unsafe void CopyTo(T[] destination, int startIndex) { if (destination == null) { throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef); } if (startIndex < 0 || startIndex >= destination.Length) { throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex)); } if (destination.Length - startIndex < Count) { throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex)); } if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { fixed (byte* ptr = (byte[])(object)destination) { for (int i = 0; i < Count; i++) { ptr[startIndex + i] = (byte)(object)this[i]; } } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr2 = (sbyte[])(object)destination) { for (int j = 0; j < Count; j++) { ptr2[startIndex + j] = (sbyte)(object)this[j]; } } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr3 = (ushort[])(object)destination) { for (int k = 0; k < Count; k++) { ptr3[startIndex + k] = (ushort)(object)this[k]; } } } else if (typeof(T) == typeof(short)) { fixed (short* ptr4 = (short[])(object)destination) { for (int l = 0; l < Count; l++) { ptr4[startIndex + l] = (short)(object)this[l]; } } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr5 = (uint[])(object)destination) { for (int m = 0; m < Count; m++) { ptr5[startIndex + m] = (uint)(object)this[m]; } } } else if (typeof(T) == typeof(int)) { fixed (int* ptr6 = (int[])(object)destination) { for (int n = 0; n < Count; n++) { ptr6[startIndex + n] = (int)(object)this[n]; } } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr7 = (ulong[])(object)destination) { for (int num = 0; num < Count; num++) { ptr7[startIndex + num] = (ulong)(object)this[num]; } } } else if (typeof(T) == typeof(long)) { fixed (long* ptr8 = (long[])(object)destination) { for (int num2 = 0; num2 < Count; num2++) { ptr8[startIndex + num2] = (long)(object)this[num2]; } } } else if (typeof(T) == typeof(float)) { fixed (float* ptr9 = (float[])(object)destination) { for (int num3 = 0; num3 < Count; num3++) { ptr9[startIndex + num3] = (float)(object)this[num3]; } } } else { if (!(typeof(T) == typeof(double))) { return; } fixed (double* ptr10 = (double[])(object)destination) { for (int num4 = 0; num4 < Count; num4++) { ptr10[startIndex + num4] = (double)(object)this[num4]; } } } } else if (typeof(T) == typeof(byte)) { fixed (byte* ptr11 = (byte[])(object)destination) { ptr11[startIndex] = register.byte_0; ptr11[startIndex + 1] = register.byte_1; ptr11[startIndex + 2] = register.byte_2; ptr11[startIndex + 3] = register.byte_3; ptr11[startIndex + 4] = register.byte_4; ptr11[startIndex + 5] = register.byte_5; ptr11[startIndex + 6] = register.byte_6; ptr11[startIndex + 7] = register.byte_7; ptr11[startIndex + 8] = register.byte_8; ptr11[startIndex + 9] = register.byte_9; ptr11[startIndex + 10] = register.byte_10; ptr11[startIndex + 11] = register.byte_11; ptr11[startIndex + 12] = register.byte_12; ptr11[startIndex + 13] = register.byte_13; ptr11[startIndex + 14] = register.byte_14; ptr11[startIndex + 15] = register.byte_15; } } else if (typeof(T) == typeof(sbyte)) { fixed (sbyte* ptr12 = (sbyte[])(object)destination) { ptr12[startIndex] = register.sbyte_0; ptr12[startIndex + 1] = register.sbyte_1; ptr12[startIndex + 2] = register.sbyte_2; ptr12[startIndex + 3] = register.sbyte_3; ptr12[startIndex + 4] = register.sbyte_4; ptr12[startIndex + 5] = register.sbyte_5; ptr12[startIndex + 6] = register.sbyte_6; ptr12[startIndex + 7] = register.sbyte_7; ptr12[startIndex + 8] = register.sbyte_8; ptr12[startIndex + 9] = register.sbyte_9; ptr12[startIndex + 10] = register.sbyte_10; ptr12[startIndex + 11] = register.sbyte_11; ptr12[startIndex + 12] = register.sbyte_12; ptr12[startIndex + 13] = register.sbyte_13; ptr12[startIndex + 14] = register.sbyte_14; ptr12[startIndex + 15] = register.sbyte_15; } } else if (typeof(T) == typeof(ushort)) { fixed (ushort* ptr13 = (ushort[])(object)destination) { ptr13[startIndex] = register.uint16_0; ptr13[startIndex + 1] = register.uint16_1; ptr13[startIndex + 2] = register.uint16_2; ptr13[startIndex + 3] = register.uint16_3; ptr13[startIndex + 4] = register.uint16_4; ptr13[startIndex + 5] = register.uint16_5; ptr13[startIndex + 6] = register.uint16_6; ptr13[startIndex + 7] = register.uint16_7; } } else if (typeof(T) == typeof(short)) { fixed (short* ptr14 = (short[])(object)destination) { ptr14[startIndex] = register.int16_0; ptr14[startIndex + 1] = register.int16_1; ptr14[startIndex + 2] = register.int16_2; ptr14[startIndex + 3] = register.int16_3; ptr14[startIndex + 4] = register.int16_4; ptr14[startIndex + 5] = register.int16_5; ptr14[startIndex + 6] = register.int16_6; ptr14[startIndex + 7] = register.int16_7; } } else if (typeof(T) == typeof(uint)) { fixed (uint* ptr15 = (uint[])(object)destination) { ptr15[startIndex] = register.uint32_0; ptr15[startIndex + 1] = register.uint32_1; ptr15[startIndex + 2] = register.uint32_2; ptr15[startIndex + 3] = register.uint32_3; } } else if (typeof(T) == typeof(int)) { fixed (int* ptr16 = (int[])(object)destination) { ptr16[startIndex] = register.int32_0; ptr16[startIndex + 1] = register.int32_1; ptr16[startIndex + 2] = register.int32_2; ptr16[startIndex + 3] = register.int32_3; } } else if (typeof(T) == typeof(ulong)) { fixed (ulong* ptr17 = (ulong[])(object)destination) { ptr17[startIndex] = register.uint64_0; ptr17[startIndex + 1] = register.uint64_1; } } else if (typeof(T) == typeof(long)) { fixed (long* ptr18 = (long[])(object)destination) { ptr18[startIndex] = register.int64_0; ptr18[startIndex + 1] = register.int64_1; } } else if (typeof(T) == typeof(float)) { fixed (float* ptr19 = (float[])(object)destination) { ptr19[startIndex] = register.single_0; ptr19[startIndex + 1] = register.single_1; ptr19[startIndex + 2] = register.single_2; ptr19[startIndex + 3] = register.single_3; } } else if (typeof(T) == typeof(double)) { fixed (double* ptr20 = (double[])(object)destination) { ptr20[startIndex] = register.double_0; ptr20[startIndex + 1] = register.double_1; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object obj) { if (!(obj is Vector)) { return false; } return Equals((Vector)obj); } [System.Runtime.CompilerServices.Intrinsic] public bool Equals(Vector 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 operator +(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]); } return new Vector(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(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(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(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(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(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(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(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(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); 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 operator -(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]); } return new Vector(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(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(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(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(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(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(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(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(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); 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 operator *(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]); } return new Vector(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(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(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(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(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(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(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(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(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); 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 operator *(Vector value, T factor) { if (Vector.IsHardwareAccelerated) { return new Vector(factor) * value; } Vector result = default(Vector); 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 operator *(T factor, Vector value) { if (Vector.IsHardwareAccelerated) { return new Vector(factor) * value; } Vector result = default(Vector); 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 operator /(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]); } return new Vector(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(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(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(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(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(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(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(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(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); 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 operator -(Vector value) { return Zero - value; } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector operator &(Vector left, Vector right) { Vector result = default(Vector); 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.Count; i++) { ptr[i] = ptr2[i] & ptr3[i]; } } else { result.register.int64_0 = left.register.int64_0 & right.register.int64_0; result.register.int64_1 = left.register.int64_1 & right.register.int64_1; } return result; } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector operator |(Vector left, Vector right) { Vector result = default(Vector); 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.Count; i++) { ptr[i] = ptr2[i] | ptr3[i]; } } else { result.register.int64_0 = left.register.int64_0 | right.register.int64_0; result.register.int64_1 = left.register.int64_1 | right.register.int64_1; } return result; } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector operator ^(Vector left, Vector right) { Vector result = default(Vector); 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.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 operator ~(Vector value) { return s_allOnes ^ value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector left, Vector right) { return left.Equals(right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector left, Vector right) { return !(left == right); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [System.Runtime.CompilerServices.Intrinsic] public static explicit operator Vector(Vector value) { return new Vector(ref value.register); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector Equals(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(ScalarEquals(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(ScalarEquals(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(ScalarEquals(left[k], right[k]) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(ScalarEquals(left[l], right[l]) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (ScalarEquals(left[m], right[m]) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (ScalarEquals(left[n], right[n]) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ScalarEquals(left[num], right[num]) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (ScalarEquals(left[num2], right[num2]) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (ScalarEquals(left[num3], right[num3]) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (ScalarEquals(left[num4], right[num4]) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Register existingRegister = default(Register); if (typeof(T) == typeof(byte)) { existingRegister.byte_0 = (byte)((left.register.byte_0 == right.register.byte_0) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_1 = (byte)((left.register.byte_1 == right.register.byte_1) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_2 = (byte)((left.register.byte_2 == right.register.byte_2) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_3 = (byte)((left.register.byte_3 == right.register.byte_3) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_4 = (byte)((left.register.byte_4 == right.register.byte_4) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_5 = (byte)((left.register.byte_5 == right.register.byte_5) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_6 = (byte)((left.register.byte_6 == right.register.byte_6) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_7 = (byte)((left.register.byte_7 == right.register.byte_7) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_8 = (byte)((left.register.byte_8 == right.register.byte_8) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_9 = (byte)((left.register.byte_9 == right.register.byte_9) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_10 = (byte)((left.register.byte_10 == right.register.byte_10) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_11 = (byte)((left.register.byte_11 == right.register.byte_11) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_12 = (byte)((left.register.byte_12 == right.register.byte_12) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_13 = (byte)((left.register.byte_13 == right.register.byte_13) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_14 = (byte)((left.register.byte_14 == right.register.byte_14) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_15 = (byte)((left.register.byte_15 == right.register.byte_15) ? ConstantHelper.GetByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(sbyte)) { existingRegister.sbyte_0 = (sbyte)((left.register.sbyte_0 == right.register.sbyte_0) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_1 = (sbyte)((left.register.sbyte_1 == right.register.sbyte_1) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_2 = (sbyte)((left.register.sbyte_2 == right.register.sbyte_2) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_3 = (sbyte)((left.register.sbyte_3 == right.register.sbyte_3) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_4 = (sbyte)((left.register.sbyte_4 == right.register.sbyte_4) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_5 = (sbyte)((left.register.sbyte_5 == right.register.sbyte_5) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_6 = (sbyte)((left.register.sbyte_6 == right.register.sbyte_6) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_7 = (sbyte)((left.register.sbyte_7 == right.register.sbyte_7) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_8 = (sbyte)((left.register.sbyte_8 == right.register.sbyte_8) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_9 = (sbyte)((left.register.sbyte_9 == right.register.sbyte_9) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_10 = (sbyte)((left.register.sbyte_10 == right.register.sbyte_10) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_11 = (sbyte)((left.register.sbyte_11 == right.register.sbyte_11) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_12 = (sbyte)((left.register.sbyte_12 == right.register.sbyte_12) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_13 = (sbyte)((left.register.sbyte_13 == right.register.sbyte_13) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_14 = (sbyte)((left.register.sbyte_14 == right.register.sbyte_14) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_15 = (sbyte)((left.register.sbyte_15 == right.register.sbyte_15) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ushort)) { existingRegister.uint16_0 = (ushort)((left.register.uint16_0 == right.register.uint16_0) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_1 = (ushort)((left.register.uint16_1 == right.register.uint16_1) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_2 = (ushort)((left.register.uint16_2 == right.register.uint16_2) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_3 = (ushort)((left.register.uint16_3 == right.register.uint16_3) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_4 = (ushort)((left.register.uint16_4 == right.register.uint16_4) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_5 = (ushort)((left.register.uint16_5 == right.register.uint16_5) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_6 = (ushort)((left.register.uint16_6 == right.register.uint16_6) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_7 = (ushort)((left.register.uint16_7 == right.register.uint16_7) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(short)) { existingRegister.int16_0 = (short)((left.register.int16_0 == right.register.int16_0) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_1 = (short)((left.register.int16_1 == right.register.int16_1) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_2 = (short)((left.register.int16_2 == right.register.int16_2) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_3 = (short)((left.register.int16_3 == right.register.int16_3) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_4 = (short)((left.register.int16_4 == right.register.int16_4) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_5 = (short)((left.register.int16_5 == right.register.int16_5) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_6 = (short)((left.register.int16_6 == right.register.int16_6) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_7 = (short)((left.register.int16_7 == right.register.int16_7) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(uint)) { existingRegister.uint32_0 = ((left.register.uint32_0 == right.register.uint32_0) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_1 = ((left.register.uint32_1 == right.register.uint32_1) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_2 = ((left.register.uint32_2 == right.register.uint32_2) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_3 = ((left.register.uint32_3 == right.register.uint32_3) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); return new Vector(ref existingRegister); } if (typeof(T) == typeof(int)) { existingRegister.int32_0 = ((left.register.int32_0 == right.register.int32_0) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_1 = ((left.register.int32_1 == right.register.int32_1) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_2 = ((left.register.int32_2 == right.register.int32_2) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_3 = ((left.register.int32_3 == right.register.int32_3) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ulong)) { existingRegister.uint64_0 = ((left.register.uint64_0 == right.register.uint64_0) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); existingRegister.uint64_1 = ((left.register.uint64_1 == right.register.uint64_1) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(long)) { existingRegister.int64_0 = ((left.register.int64_0 == right.register.int64_0) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); existingRegister.int64_1 = ((left.register.int64_1 == right.register.int64_1) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(float)) { existingRegister.single_0 = ((left.register.single_0 == right.register.single_0) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_1 = ((left.register.single_1 == right.register.single_1) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_2 = ((left.register.single_2 == right.register.single_2) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_3 = ((left.register.single_3 == right.register.single_3) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); return new Vector(ref existingRegister); } if (typeof(T) == typeof(double)) { existingRegister.double_0 = ((left.register.double_0 == right.register.double_0) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); existingRegister.double_1 = ((left.register.double_1 == right.register.double_1) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); return new Vector(ref existingRegister); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector LessThan(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(ScalarLessThan(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(ScalarLessThan(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(ScalarLessThan(left[k], right[k]) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(ScalarLessThan(left[l], right[l]) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (ScalarLessThan(left[m], right[m]) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (ScalarLessThan(left[n], right[n]) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ScalarLessThan(left[num], right[num]) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (ScalarLessThan(left[num2], right[num2]) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (ScalarLessThan(left[num3], right[num3]) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (ScalarLessThan(left[num4], right[num4]) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Register existingRegister = default(Register); if (typeof(T) == typeof(byte)) { existingRegister.byte_0 = (byte)((left.register.byte_0 < right.register.byte_0) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_1 = (byte)((left.register.byte_1 < right.register.byte_1) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_2 = (byte)((left.register.byte_2 < right.register.byte_2) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_3 = (byte)((left.register.byte_3 < right.register.byte_3) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_4 = (byte)((left.register.byte_4 < right.register.byte_4) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_5 = (byte)((left.register.byte_5 < right.register.byte_5) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_6 = (byte)((left.register.byte_6 < right.register.byte_6) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_7 = (byte)((left.register.byte_7 < right.register.byte_7) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_8 = (byte)((left.register.byte_8 < right.register.byte_8) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_9 = (byte)((left.register.byte_9 < right.register.byte_9) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_10 = (byte)((left.register.byte_10 < right.register.byte_10) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_11 = (byte)((left.register.byte_11 < right.register.byte_11) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_12 = (byte)((left.register.byte_12 < right.register.byte_12) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_13 = (byte)((left.register.byte_13 < right.register.byte_13) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_14 = (byte)((left.register.byte_14 < right.register.byte_14) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_15 = (byte)((left.register.byte_15 < right.register.byte_15) ? ConstantHelper.GetByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(sbyte)) { existingRegister.sbyte_0 = (sbyte)((left.register.sbyte_0 < right.register.sbyte_0) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_1 = (sbyte)((left.register.sbyte_1 < right.register.sbyte_1) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_2 = (sbyte)((left.register.sbyte_2 < right.register.sbyte_2) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_3 = (sbyte)((left.register.sbyte_3 < right.register.sbyte_3) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_4 = (sbyte)((left.register.sbyte_4 < right.register.sbyte_4) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_5 = (sbyte)((left.register.sbyte_5 < right.register.sbyte_5) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_6 = (sbyte)((left.register.sbyte_6 < right.register.sbyte_6) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_7 = (sbyte)((left.register.sbyte_7 < right.register.sbyte_7) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_8 = (sbyte)((left.register.sbyte_8 < right.register.sbyte_8) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_9 = (sbyte)((left.register.sbyte_9 < right.register.sbyte_9) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_10 = (sbyte)((left.register.sbyte_10 < right.register.sbyte_10) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_11 = (sbyte)((left.register.sbyte_11 < right.register.sbyte_11) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_12 = (sbyte)((left.register.sbyte_12 < right.register.sbyte_12) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_13 = (sbyte)((left.register.sbyte_13 < right.register.sbyte_13) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_14 = (sbyte)((left.register.sbyte_14 < right.register.sbyte_14) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_15 = (sbyte)((left.register.sbyte_15 < right.register.sbyte_15) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ushort)) { existingRegister.uint16_0 = (ushort)((left.register.uint16_0 < right.register.uint16_0) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_1 = (ushort)((left.register.uint16_1 < right.register.uint16_1) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_2 = (ushort)((left.register.uint16_2 < right.register.uint16_2) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_3 = (ushort)((left.register.uint16_3 < right.register.uint16_3) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_4 = (ushort)((left.register.uint16_4 < right.register.uint16_4) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_5 = (ushort)((left.register.uint16_5 < right.register.uint16_5) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_6 = (ushort)((left.register.uint16_6 < right.register.uint16_6) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_7 = (ushort)((left.register.uint16_7 < right.register.uint16_7) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(short)) { existingRegister.int16_0 = (short)((left.register.int16_0 < right.register.int16_0) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_1 = (short)((left.register.int16_1 < right.register.int16_1) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_2 = (short)((left.register.int16_2 < right.register.int16_2) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_3 = (short)((left.register.int16_3 < right.register.int16_3) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_4 = (short)((left.register.int16_4 < right.register.int16_4) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_5 = (short)((left.register.int16_5 < right.register.int16_5) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_6 = (short)((left.register.int16_6 < right.register.int16_6) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_7 = (short)((left.register.int16_7 < right.register.int16_7) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(uint)) { existingRegister.uint32_0 = ((left.register.uint32_0 < right.register.uint32_0) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_1 = ((left.register.uint32_1 < right.register.uint32_1) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_2 = ((left.register.uint32_2 < right.register.uint32_2) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_3 = ((left.register.uint32_3 < right.register.uint32_3) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); return new Vector(ref existingRegister); } if (typeof(T) == typeof(int)) { existingRegister.int32_0 = ((left.register.int32_0 < right.register.int32_0) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_1 = ((left.register.int32_1 < right.register.int32_1) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_2 = ((left.register.int32_2 < right.register.int32_2) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_3 = ((left.register.int32_3 < right.register.int32_3) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ulong)) { existingRegister.uint64_0 = ((left.register.uint64_0 < right.register.uint64_0) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); existingRegister.uint64_1 = ((left.register.uint64_1 < right.register.uint64_1) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(long)) { existingRegister.int64_0 = ((left.register.int64_0 < right.register.int64_0) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); existingRegister.int64_1 = ((left.register.int64_1 < right.register.int64_1) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(float)) { existingRegister.single_0 = ((left.register.single_0 < right.register.single_0) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_1 = ((left.register.single_1 < right.register.single_1) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_2 = ((left.register.single_2 < right.register.single_2) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_3 = ((left.register.single_3 < right.register.single_3) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); return new Vector(ref existingRegister); } if (typeof(T) == typeof(double)) { existingRegister.double_0 = ((left.register.double_0 < right.register.double_0) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); existingRegister.double_1 = ((left.register.double_1 < right.register.double_1) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); return new Vector(ref existingRegister); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector GreaterThan(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)(ScalarGreaterThan(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)(ScalarGreaterThan(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)(ScalarGreaterThan(left[k], right[k]) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)(ScalarGreaterThan(left[l], right[l]) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (ScalarGreaterThan(left[m], right[m]) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (ScalarGreaterThan(left[n], right[n]) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ScalarGreaterThan(left[num], right[num]) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (ScalarGreaterThan(left[num2], right[num2]) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (ScalarGreaterThan(left[num3], right[num3]) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (ScalarGreaterThan(left[num4], right[num4]) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Register existingRegister = default(Register); if (typeof(T) == typeof(byte)) { existingRegister.byte_0 = (byte)((left.register.byte_0 > right.register.byte_0) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_1 = (byte)((left.register.byte_1 > right.register.byte_1) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_2 = (byte)((left.register.byte_2 > right.register.byte_2) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_3 = (byte)((left.register.byte_3 > right.register.byte_3) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_4 = (byte)((left.register.byte_4 > right.register.byte_4) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_5 = (byte)((left.register.byte_5 > right.register.byte_5) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_6 = (byte)((left.register.byte_6 > right.register.byte_6) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_7 = (byte)((left.register.byte_7 > right.register.byte_7) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_8 = (byte)((left.register.byte_8 > right.register.byte_8) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_9 = (byte)((left.register.byte_9 > right.register.byte_9) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_10 = (byte)((left.register.byte_10 > right.register.byte_10) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_11 = (byte)((left.register.byte_11 > right.register.byte_11) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_12 = (byte)((left.register.byte_12 > right.register.byte_12) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_13 = (byte)((left.register.byte_13 > right.register.byte_13) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_14 = (byte)((left.register.byte_14 > right.register.byte_14) ? ConstantHelper.GetByteWithAllBitsSet() : 0); existingRegister.byte_15 = (byte)((left.register.byte_15 > right.register.byte_15) ? ConstantHelper.GetByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(sbyte)) { existingRegister.sbyte_0 = (sbyte)((left.register.sbyte_0 > right.register.sbyte_0) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_1 = (sbyte)((left.register.sbyte_1 > right.register.sbyte_1) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_2 = (sbyte)((left.register.sbyte_2 > right.register.sbyte_2) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_3 = (sbyte)((left.register.sbyte_3 > right.register.sbyte_3) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_4 = (sbyte)((left.register.sbyte_4 > right.register.sbyte_4) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_5 = (sbyte)((left.register.sbyte_5 > right.register.sbyte_5) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_6 = (sbyte)((left.register.sbyte_6 > right.register.sbyte_6) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_7 = (sbyte)((left.register.sbyte_7 > right.register.sbyte_7) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_8 = (sbyte)((left.register.sbyte_8 > right.register.sbyte_8) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_9 = (sbyte)((left.register.sbyte_9 > right.register.sbyte_9) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_10 = (sbyte)((left.register.sbyte_10 > right.register.sbyte_10) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_11 = (sbyte)((left.register.sbyte_11 > right.register.sbyte_11) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_12 = (sbyte)((left.register.sbyte_12 > right.register.sbyte_12) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_13 = (sbyte)((left.register.sbyte_13 > right.register.sbyte_13) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_14 = (sbyte)((left.register.sbyte_14 > right.register.sbyte_14) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); existingRegister.sbyte_15 = (sbyte)((left.register.sbyte_15 > right.register.sbyte_15) ? ConstantHelper.GetSByteWithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ushort)) { existingRegister.uint16_0 = (ushort)((left.register.uint16_0 > right.register.uint16_0) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_1 = (ushort)((left.register.uint16_1 > right.register.uint16_1) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_2 = (ushort)((left.register.uint16_2 > right.register.uint16_2) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_3 = (ushort)((left.register.uint16_3 > right.register.uint16_3) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_4 = (ushort)((left.register.uint16_4 > right.register.uint16_4) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_5 = (ushort)((left.register.uint16_5 > right.register.uint16_5) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_6 = (ushort)((left.register.uint16_6 > right.register.uint16_6) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); existingRegister.uint16_7 = (ushort)((left.register.uint16_7 > right.register.uint16_7) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(short)) { existingRegister.int16_0 = (short)((left.register.int16_0 > right.register.int16_0) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_1 = (short)((left.register.int16_1 > right.register.int16_1) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_2 = (short)((left.register.int16_2 > right.register.int16_2) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_3 = (short)((left.register.int16_3 > right.register.int16_3) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_4 = (short)((left.register.int16_4 > right.register.int16_4) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_5 = (short)((left.register.int16_5 > right.register.int16_5) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_6 = (short)((left.register.int16_6 > right.register.int16_6) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); existingRegister.int16_7 = (short)((left.register.int16_7 > right.register.int16_7) ? ConstantHelper.GetInt16WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(uint)) { existingRegister.uint32_0 = ((left.register.uint32_0 > right.register.uint32_0) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_1 = ((left.register.uint32_1 > right.register.uint32_1) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_2 = ((left.register.uint32_2 > right.register.uint32_2) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); existingRegister.uint32_3 = ((left.register.uint32_3 > right.register.uint32_3) ? ConstantHelper.GetUInt32WithAllBitsSet() : 0u); return new Vector(ref existingRegister); } if (typeof(T) == typeof(int)) { existingRegister.int32_0 = ((left.register.int32_0 > right.register.int32_0) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_1 = ((left.register.int32_1 > right.register.int32_1) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_2 = ((left.register.int32_2 > right.register.int32_2) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); existingRegister.int32_3 = ((left.register.int32_3 > right.register.int32_3) ? ConstantHelper.GetInt32WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(ulong)) { existingRegister.uint64_0 = ((left.register.uint64_0 > right.register.uint64_0) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); existingRegister.uint64_1 = ((left.register.uint64_1 > right.register.uint64_1) ? ConstantHelper.GetUInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(long)) { existingRegister.int64_0 = ((left.register.int64_0 > right.register.int64_0) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); existingRegister.int64_1 = ((left.register.int64_1 > right.register.int64_1) ? ConstantHelper.GetInt64WithAllBitsSet() : 0); return new Vector(ref existingRegister); } if (typeof(T) == typeof(float)) { existingRegister.single_0 = ((left.register.single_0 > right.register.single_0) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_1 = ((left.register.single_1 > right.register.single_1) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_2 = ((left.register.single_2 > right.register.single_2) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); existingRegister.single_3 = ((left.register.single_3 > right.register.single_3) ? ConstantHelper.GetSingleWithAllBitsSet() : 0f); return new Vector(ref existingRegister); } if (typeof(T) == typeof(double)) { existingRegister.double_0 = ((left.register.double_0 > right.register.double_0) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); existingRegister.double_1 = ((left.register.double_1 > right.register.double_1) ? ConstantHelper.GetDoubleWithAllBitsSet() : 0.0); return new Vector(ref existingRegister); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [System.Runtime.CompilerServices.Intrinsic] internal static Vector GreaterThanOrEqual(Vector left, Vector right) { return Equals(left, right) | GreaterThan(left, right); } [System.Runtime.CompilerServices.Intrinsic] internal static Vector LessThanOrEqual(Vector left, Vector right) { return Equals(left, right) | LessThan(left, right); } [System.Runtime.CompilerServices.Intrinsic] internal static Vector ConditionalSelect(Vector condition, Vector left, Vector right) { return (left & condition) | Vector.AndNot(right, condition); } [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector Abs(Vector value) { if (typeof(T) == typeof(byte)) { return value; } if (typeof(T) == typeof(ushort)) { return value; } if (typeof(T) == typeof(uint)) { return value; } if (typeof(T) == typeof(ulong)) { return value; } if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(sbyte)) { sbyte* ptr = stackalloc sbyte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (sbyte)(object)Math.Abs((sbyte)(object)value[i]); } return new Vector(ptr); } if (typeof(T) == typeof(short)) { short* ptr2 = stackalloc short[Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (short)(object)Math.Abs((short)(object)value[j]); } return new Vector(ptr2); } if (typeof(T) == typeof(int)) { int* ptr3 = stackalloc int[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (int)(object)Math.Abs((int)(object)value[k]); } return new Vector(ptr3); } if (typeof(T) == typeof(long)) { long* ptr4 = stackalloc long[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (long)(object)Math.Abs((long)(object)value[l]); } return new Vector(ptr4); } if (typeof(T) == typeof(float)) { float* ptr5 = stackalloc float[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (float)(object)Math.Abs((float)(object)value[m]); } return new Vector(ptr5); } if (typeof(T) == typeof(double)) { double* ptr6 = stackalloc double[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (double)(object)Math.Abs((double)(object)value[n]); } return new Vector(ptr6); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } if (typeof(T) == typeof(sbyte)) { value.register.sbyte_0 = Math.Abs(value.register.sbyte_0); value.register.sbyte_1 = Math.Abs(value.register.sbyte_1); value.register.sbyte_2 = Math.Abs(value.register.sbyte_2); value.register.sbyte_3 = Math.Abs(value.register.sbyte_3); value.register.sbyte_4 = Math.Abs(value.register.sbyte_4); value.register.sbyte_5 = Math.Abs(value.register.sbyte_5); value.register.sbyte_6 = Math.Abs(value.register.sbyte_6); value.register.sbyte_7 = Math.Abs(value.register.sbyte_7); value.register.sbyte_8 = Math.Abs(value.register.sbyte_8); value.register.sbyte_9 = Math.Abs(value.register.sbyte_9); value.register.sbyte_10 = Math.Abs(value.register.sbyte_10); value.register.sbyte_11 = Math.Abs(value.register.sbyte_11); value.register.sbyte_12 = Math.Abs(value.register.sbyte_12); value.register.sbyte_13 = Math.Abs(value.register.sbyte_13); value.register.sbyte_14 = Math.Abs(value.register.sbyte_14); value.register.sbyte_15 = Math.Abs(value.register.sbyte_15); return value; } if (typeof(T) == typeof(short)) { value.register.int16_0 = Math.Abs(value.register.int16_0); value.register.int16_1 = Math.Abs(value.register.int16_1); value.register.int16_2 = Math.Abs(value.register.int16_2); value.register.int16_3 = Math.Abs(value.register.int16_3); value.register.int16_4 = Math.Abs(value.register.int16_4); value.register.int16_5 = Math.Abs(value.register.int16_5); value.register.int16_6 = Math.Abs(value.register.int16_6); value.register.int16_7 = Math.Abs(value.register.int16_7); return value; } if (typeof(T) == typeof(int)) { value.register.int32_0 = Math.Abs(value.register.int32_0); value.register.int32_1 = Math.Abs(value.register.int32_1); value.register.int32_2 = Math.Abs(value.register.int32_2); value.register.int32_3 = Math.Abs(value.register.int32_3); return value; } if (typeof(T) == typeof(long)) { value.register.int64_0 = Math.Abs(value.register.int64_0); value.register.int64_1 = Math.Abs(value.register.int64_1); return value; } if (typeof(T) == typeof(float)) { value.register.single_0 = Math.Abs(value.register.single_0); value.register.single_1 = Math.Abs(value.register.single_1); value.register.single_2 = Math.Abs(value.register.single_2); value.register.single_3 = Math.Abs(value.register.single_3); return value; } if (typeof(T) == typeof(double)) { value.register.double_0 = Math.Abs(value.register.double_0); value.register.double_1 = Math.Abs(value.register.double_1); return value; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector Min(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (ScalarLessThan(left[i], right[i]) ? ((byte)(object)left[i]) : ((byte)(object)right[i])); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (ScalarLessThan(left[j], right[j]) ? ((sbyte)(object)left[j]) : ((sbyte)(object)right[j])); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ScalarLessThan(left[k], right[k]) ? ((ushort)(object)left[k]) : ((ushort)(object)right[k])); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (ScalarLessThan(left[l], right[l]) ? ((short)(object)left[l]) : ((short)(object)right[l])); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (ScalarLessThan(left[m], right[m]) ? ((uint)(object)left[m]) : ((uint)(object)right[m])); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (ScalarLessThan(left[n], right[n]) ? ((int)(object)left[n]) : ((int)(object)right[n])); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ScalarLessThan(left[num], right[num]) ? ((ulong)(object)left[num]) : ((ulong)(object)right[num])); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (ScalarLessThan(left[num2], right[num2]) ? ((long)(object)left[num2]) : ((long)(object)right[num2])); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (ScalarLessThan(left[num3], right[num3]) ? ((float)(object)left[num3]) : ((float)(object)right[num3])); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (ScalarLessThan(left[num4], right[num4]) ? ((double)(object)left[num4]) : ((double)(object)right[num4])); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); if (typeof(T) == typeof(byte)) { result.register.byte_0 = ((left.register.byte_0 < right.register.byte_0) ? left.register.byte_0 : right.register.byte_0); result.register.byte_1 = ((left.register.byte_1 < right.register.byte_1) ? left.register.byte_1 : right.register.byte_1); result.register.byte_2 = ((left.register.byte_2 < right.register.byte_2) ? left.register.byte_2 : right.register.byte_2); result.register.byte_3 = ((left.register.byte_3 < right.register.byte_3) ? left.register.byte_3 : right.register.byte_3); result.register.byte_4 = ((left.register.byte_4 < right.register.byte_4) ? left.register.byte_4 : right.register.byte_4); result.register.byte_5 = ((left.register.byte_5 < right.register.byte_5) ? left.register.byte_5 : right.register.byte_5); result.register.byte_6 = ((left.register.byte_6 < right.register.byte_6) ? left.register.byte_6 : right.register.byte_6); result.register.byte_7 = ((left.register.byte_7 < right.register.byte_7) ? left.register.byte_7 : right.register.byte_7); result.register.byte_8 = ((left.register.byte_8 < right.register.byte_8) ? left.register.byte_8 : right.register.byte_8); result.register.byte_9 = ((left.register.byte_9 < right.register.byte_9) ? left.register.byte_9 : right.register.byte_9); result.register.byte_10 = ((left.register.byte_10 < right.register.byte_10) ? left.register.byte_10 : right.register.byte_10); result.register.byte_11 = ((left.register.byte_11 < right.register.byte_11) ? left.register.byte_11 : right.register.byte_11); result.register.byte_12 = ((left.register.byte_12 < right.register.byte_12) ? left.register.byte_12 : right.register.byte_12); result.register.byte_13 = ((left.register.byte_13 < right.register.byte_13) ? left.register.byte_13 : right.register.byte_13); result.register.byte_14 = ((left.register.byte_14 < right.register.byte_14) ? left.register.byte_14 : right.register.byte_14); result.register.byte_15 = ((left.register.byte_15 < right.register.byte_15) ? left.register.byte_15 : right.register.byte_15); return result; } if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = ((left.register.sbyte_0 < right.register.sbyte_0) ? left.register.sbyte_0 : right.register.sbyte_0); result.register.sbyte_1 = ((left.register.sbyte_1 < right.register.sbyte_1) ? left.register.sbyte_1 : right.register.sbyte_1); result.register.sbyte_2 = ((left.register.sbyte_2 < right.register.sbyte_2) ? left.register.sbyte_2 : right.register.sbyte_2); result.register.sbyte_3 = ((left.register.sbyte_3 < right.register.sbyte_3) ? left.register.sbyte_3 : right.register.sbyte_3); result.register.sbyte_4 = ((left.register.sbyte_4 < right.register.sbyte_4) ? left.register.sbyte_4 : right.register.sbyte_4); result.register.sbyte_5 = ((left.register.sbyte_5 < right.register.sbyte_5) ? left.register.sbyte_5 : right.register.sbyte_5); result.register.sbyte_6 = ((left.register.sbyte_6 < right.register.sbyte_6) ? left.register.sbyte_6 : right.register.sbyte_6); result.register.sbyte_7 = ((left.register.sbyte_7 < right.register.sbyte_7) ? left.register.sbyte_7 : right.register.sbyte_7); result.register.sbyte_8 = ((left.register.sbyte_8 < right.register.sbyte_8) ? left.register.sbyte_8 : right.register.sbyte_8); result.register.sbyte_9 = ((left.register.sbyte_9 < right.register.sbyte_9) ? left.register.sbyte_9 : right.register.sbyte_9); result.register.sbyte_10 = ((left.register.sbyte_10 < right.register.sbyte_10) ? left.register.sbyte_10 : right.register.sbyte_10); result.register.sbyte_11 = ((left.register.sbyte_11 < right.register.sbyte_11) ? left.register.sbyte_11 : right.register.sbyte_11); result.register.sbyte_12 = ((left.register.sbyte_12 < right.register.sbyte_12) ? left.register.sbyte_12 : right.register.sbyte_12); result.register.sbyte_13 = ((left.register.sbyte_13 < right.register.sbyte_13) ? left.register.sbyte_13 : right.register.sbyte_13); result.register.sbyte_14 = ((left.register.sbyte_14 < right.register.sbyte_14) ? left.register.sbyte_14 : right.register.sbyte_14); result.register.sbyte_15 = ((left.register.sbyte_15 < right.register.sbyte_15) ? left.register.sbyte_15 : right.register.sbyte_15); return result; } if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = ((left.register.uint16_0 < right.register.uint16_0) ? left.register.uint16_0 : right.register.uint16_0); result.register.uint16_1 = ((left.register.uint16_1 < right.register.uint16_1) ? left.register.uint16_1 : right.register.uint16_1); result.register.uint16_2 = ((left.register.uint16_2 < right.register.uint16_2) ? left.register.uint16_2 : right.register.uint16_2); result.register.uint16_3 = ((left.register.uint16_3 < right.register.uint16_3) ? left.register.uint16_3 : right.register.uint16_3); result.register.uint16_4 = ((left.register.uint16_4 < right.register.uint16_4) ? left.register.uint16_4 : right.register.uint16_4); result.register.uint16_5 = ((left.register.uint16_5 < right.register.uint16_5) ? left.register.uint16_5 : right.register.uint16_5); result.register.uint16_6 = ((left.register.uint16_6 < right.register.uint16_6) ? left.register.uint16_6 : right.register.uint16_6); result.register.uint16_7 = ((left.register.uint16_7 < right.register.uint16_7) ? left.register.uint16_7 : right.register.uint16_7); return result; } if (typeof(T) == typeof(short)) { result.register.int16_0 = ((left.register.int16_0 < right.register.int16_0) ? left.register.int16_0 : right.register.int16_0); result.register.int16_1 = ((left.register.int16_1 < right.register.int16_1) ? left.register.int16_1 : right.register.int16_1); result.register.int16_2 = ((left.register.int16_2 < right.register.int16_2) ? left.register.int16_2 : right.register.int16_2); result.register.int16_3 = ((left.register.int16_3 < right.register.int16_3) ? left.register.int16_3 : right.register.int16_3); result.register.int16_4 = ((left.register.int16_4 < right.register.int16_4) ? left.register.int16_4 : right.register.int16_4); result.register.int16_5 = ((left.register.int16_5 < right.register.int16_5) ? left.register.int16_5 : right.register.int16_5); result.register.int16_6 = ((left.register.int16_6 < right.register.int16_6) ? left.register.int16_6 : right.register.int16_6); result.register.int16_7 = ((left.register.int16_7 < right.register.int16_7) ? left.register.int16_7 : right.register.int16_7); return result; } if (typeof(T) == typeof(uint)) { result.register.uint32_0 = ((left.register.uint32_0 < right.register.uint32_0) ? left.register.uint32_0 : right.register.uint32_0); result.register.uint32_1 = ((left.register.uint32_1 < right.register.uint32_1) ? left.register.uint32_1 : right.register.uint32_1); result.register.uint32_2 = ((left.register.uint32_2 < right.register.uint32_2) ? left.register.uint32_2 : right.register.uint32_2); result.register.uint32_3 = ((left.register.uint32_3 < right.register.uint32_3) ? left.register.uint32_3 : right.register.uint32_3); return result; } if (typeof(T) == typeof(int)) { result.register.int32_0 = ((left.register.int32_0 < right.register.int32_0) ? left.register.int32_0 : right.register.int32_0); result.register.int32_1 = ((left.register.int32_1 < right.register.int32_1) ? left.register.int32_1 : right.register.int32_1); result.register.int32_2 = ((left.register.int32_2 < right.register.int32_2) ? left.register.int32_2 : right.register.int32_2); result.register.int32_3 = ((left.register.int32_3 < right.register.int32_3) ? left.register.int32_3 : right.register.int32_3); return result; } if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = ((left.register.uint64_0 < right.register.uint64_0) ? left.register.uint64_0 : right.register.uint64_0); result.register.uint64_1 = ((left.register.uint64_1 < right.register.uint64_1) ? left.register.uint64_1 : right.register.uint64_1); return result; } if (typeof(T) == typeof(long)) { result.register.int64_0 = ((left.register.int64_0 < right.register.int64_0) ? left.register.int64_0 : right.register.int64_0); result.register.int64_1 = ((left.register.int64_1 < right.register.int64_1) ? left.register.int64_1 : right.register.int64_1); return result; } if (typeof(T) == typeof(float)) { result.register.single_0 = ((left.register.single_0 < right.register.single_0) ? left.register.single_0 : right.register.single_0); result.register.single_1 = ((left.register.single_1 < right.register.single_1) ? left.register.single_1 : right.register.single_1); result.register.single_2 = ((left.register.single_2 < right.register.single_2) ? left.register.single_2 : right.register.single_2); result.register.single_3 = ((left.register.single_3 < right.register.single_3) ? left.register.single_3 : right.register.single_3); return result; } if (typeof(T) == typeof(double)) { result.register.double_0 = ((left.register.double_0 < right.register.double_0) ? left.register.double_0 : right.register.double_0); result.register.double_1 = ((left.register.double_1 < right.register.double_1) ? left.register.double_1 : right.register.double_1); return result; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector Max(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (ScalarGreaterThan(left[i], right[i]) ? ((byte)(object)left[i]) : ((byte)(object)right[i])); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (ScalarGreaterThan(left[j], right[j]) ? ((sbyte)(object)left[j]) : ((sbyte)(object)right[j])); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ScalarGreaterThan(left[k], right[k]) ? ((ushort)(object)left[k]) : ((ushort)(object)right[k])); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (ScalarGreaterThan(left[l], right[l]) ? ((short)(object)left[l]) : ((short)(object)right[l])); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (ScalarGreaterThan(left[m], right[m]) ? ((uint)(object)left[m]) : ((uint)(object)right[m])); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (ScalarGreaterThan(left[n], right[n]) ? ((int)(object)left[n]) : ((int)(object)right[n])); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ScalarGreaterThan(left[num], right[num]) ? ((ulong)(object)left[num]) : ((ulong)(object)right[num])); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (ScalarGreaterThan(left[num2], right[num2]) ? ((long)(object)left[num2]) : ((long)(object)right[num2])); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (ScalarGreaterThan(left[num3], right[num3]) ? ((float)(object)left[num3]) : ((float)(object)right[num3])); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = (ScalarGreaterThan(left[num4], right[num4]) ? ((double)(object)left[num4]) : ((double)(object)right[num4])); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } Vector result = default(Vector); if (typeof(T) == typeof(byte)) { result.register.byte_0 = ((left.register.byte_0 > right.register.byte_0) ? left.register.byte_0 : right.register.byte_0); result.register.byte_1 = ((left.register.byte_1 > right.register.byte_1) ? left.register.byte_1 : right.register.byte_1); result.register.byte_2 = ((left.register.byte_2 > right.register.byte_2) ? left.register.byte_2 : right.register.byte_2); result.register.byte_3 = ((left.register.byte_3 > right.register.byte_3) ? left.register.byte_3 : right.register.byte_3); result.register.byte_4 = ((left.register.byte_4 > right.register.byte_4) ? left.register.byte_4 : right.register.byte_4); result.register.byte_5 = ((left.register.byte_5 > right.register.byte_5) ? left.register.byte_5 : right.register.byte_5); result.register.byte_6 = ((left.register.byte_6 > right.register.byte_6) ? left.register.byte_6 : right.register.byte_6); result.register.byte_7 = ((left.register.byte_7 > right.register.byte_7) ? left.register.byte_7 : right.register.byte_7); result.register.byte_8 = ((left.register.byte_8 > right.register.byte_8) ? left.register.byte_8 : right.register.byte_8); result.register.byte_9 = ((left.register.byte_9 > right.register.byte_9) ? left.register.byte_9 : right.register.byte_9); result.register.byte_10 = ((left.register.byte_10 > right.register.byte_10) ? left.register.byte_10 : right.register.byte_10); result.register.byte_11 = ((left.register.byte_11 > right.register.byte_11) ? left.register.byte_11 : right.register.byte_11); result.register.byte_12 = ((left.register.byte_12 > right.register.byte_12) ? left.register.byte_12 : right.register.byte_12); result.register.byte_13 = ((left.register.byte_13 > right.register.byte_13) ? left.register.byte_13 : right.register.byte_13); result.register.byte_14 = ((left.register.byte_14 > right.register.byte_14) ? left.register.byte_14 : right.register.byte_14); result.register.byte_15 = ((left.register.byte_15 > right.register.byte_15) ? left.register.byte_15 : right.register.byte_15); return result; } if (typeof(T) == typeof(sbyte)) { result.register.sbyte_0 = ((left.register.sbyte_0 > right.register.sbyte_0) ? left.register.sbyte_0 : right.register.sbyte_0); result.register.sbyte_1 = ((left.register.sbyte_1 > right.register.sbyte_1) ? left.register.sbyte_1 : right.register.sbyte_1); result.register.sbyte_2 = ((left.register.sbyte_2 > right.register.sbyte_2) ? left.register.sbyte_2 : right.register.sbyte_2); result.register.sbyte_3 = ((left.register.sbyte_3 > right.register.sbyte_3) ? left.register.sbyte_3 : right.register.sbyte_3); result.register.sbyte_4 = ((left.register.sbyte_4 > right.register.sbyte_4) ? left.register.sbyte_4 : right.register.sbyte_4); result.register.sbyte_5 = ((left.register.sbyte_5 > right.register.sbyte_5) ? left.register.sbyte_5 : right.register.sbyte_5); result.register.sbyte_6 = ((left.register.sbyte_6 > right.register.sbyte_6) ? left.register.sbyte_6 : right.register.sbyte_6); result.register.sbyte_7 = ((left.register.sbyte_7 > right.register.sbyte_7) ? left.register.sbyte_7 : right.register.sbyte_7); result.register.sbyte_8 = ((left.register.sbyte_8 > right.register.sbyte_8) ? left.register.sbyte_8 : right.register.sbyte_8); result.register.sbyte_9 = ((left.register.sbyte_9 > right.register.sbyte_9) ? left.register.sbyte_9 : right.register.sbyte_9); result.register.sbyte_10 = ((left.register.sbyte_10 > right.register.sbyte_10) ? left.register.sbyte_10 : right.register.sbyte_10); result.register.sbyte_11 = ((left.register.sbyte_11 > right.register.sbyte_11) ? left.register.sbyte_11 : right.register.sbyte_11); result.register.sbyte_12 = ((left.register.sbyte_12 > right.register.sbyte_12) ? left.register.sbyte_12 : right.register.sbyte_12); result.register.sbyte_13 = ((left.register.sbyte_13 > right.register.sbyte_13) ? left.register.sbyte_13 : right.register.sbyte_13); result.register.sbyte_14 = ((left.register.sbyte_14 > right.register.sbyte_14) ? left.register.sbyte_14 : right.register.sbyte_14); result.register.sbyte_15 = ((left.register.sbyte_15 > right.register.sbyte_15) ? left.register.sbyte_15 : right.register.sbyte_15); return result; } if (typeof(T) == typeof(ushort)) { result.register.uint16_0 = ((left.register.uint16_0 > right.register.uint16_0) ? left.register.uint16_0 : right.register.uint16_0); result.register.uint16_1 = ((left.register.uint16_1 > right.register.uint16_1) ? left.register.uint16_1 : right.register.uint16_1); result.register.uint16_2 = ((left.register.uint16_2 > right.register.uint16_2) ? left.register.uint16_2 : right.register.uint16_2); result.register.uint16_3 = ((left.register.uint16_3 > right.register.uint16_3) ? left.register.uint16_3 : right.register.uint16_3); result.register.uint16_4 = ((left.register.uint16_4 > right.register.uint16_4) ? left.register.uint16_4 : right.register.uint16_4); result.register.uint16_5 = ((left.register.uint16_5 > right.register.uint16_5) ? left.register.uint16_5 : right.register.uint16_5); result.register.uint16_6 = ((left.register.uint16_6 > right.register.uint16_6) ? left.register.uint16_6 : right.register.uint16_6); result.register.uint16_7 = ((left.register.uint16_7 > right.register.uint16_7) ? left.register.uint16_7 : right.register.uint16_7); return result; } if (typeof(T) == typeof(short)) { result.register.int16_0 = ((left.register.int16_0 > right.register.int16_0) ? left.register.int16_0 : right.register.int16_0); result.register.int16_1 = ((left.register.int16_1 > right.register.int16_1) ? left.register.int16_1 : right.register.int16_1); result.register.int16_2 = ((left.register.int16_2 > right.register.int16_2) ? left.register.int16_2 : right.register.int16_2); result.register.int16_3 = ((left.register.int16_3 > right.register.int16_3) ? left.register.int16_3 : right.register.int16_3); result.register.int16_4 = ((left.register.int16_4 > right.register.int16_4) ? left.register.int16_4 : right.register.int16_4); result.register.int16_5 = ((left.register.int16_5 > right.register.int16_5) ? left.register.int16_5 : right.register.int16_5); result.register.int16_6 = ((left.register.int16_6 > right.register.int16_6) ? left.register.int16_6 : right.register.int16_6); result.register.int16_7 = ((left.register.int16_7 > right.register.int16_7) ? left.register.int16_7 : right.register.int16_7); return result; } if (typeof(T) == typeof(uint)) { result.register.uint32_0 = ((left.register.uint32_0 > right.register.uint32_0) ? left.register.uint32_0 : right.register.uint32_0); result.register.uint32_1 = ((left.register.uint32_1 > right.register.uint32_1) ? left.register.uint32_1 : right.register.uint32_1); result.register.uint32_2 = ((left.register.uint32_2 > right.register.uint32_2) ? left.register.uint32_2 : right.register.uint32_2); result.register.uint32_3 = ((left.register.uint32_3 > right.register.uint32_3) ? left.register.uint32_3 : right.register.uint32_3); return result; } if (typeof(T) == typeof(int)) { result.register.int32_0 = ((left.register.int32_0 > right.register.int32_0) ? left.register.int32_0 : right.register.int32_0); result.register.int32_1 = ((left.register.int32_1 > right.register.int32_1) ? left.register.int32_1 : right.register.int32_1); result.register.int32_2 = ((left.register.int32_2 > right.register.int32_2) ? left.register.int32_2 : right.register.int32_2); result.register.int32_3 = ((left.register.int32_3 > right.register.int32_3) ? left.register.int32_3 : right.register.int32_3); return result; } if (typeof(T) == typeof(ulong)) { result.register.uint64_0 = ((left.register.uint64_0 > right.register.uint64_0) ? left.register.uint64_0 : right.register.uint64_0); result.register.uint64_1 = ((left.register.uint64_1 > right.register.uint64_1) ? left.register.uint64_1 : right.register.uint64_1); return result; } if (typeof(T) == typeof(long)) { result.register.int64_0 = ((left.register.int64_0 > right.register.int64_0) ? left.register.int64_0 : right.register.int64_0); result.register.int64_1 = ((left.register.int64_1 > right.register.int64_1) ? left.register.int64_1 : right.register.int64_1); return result; } if (typeof(T) == typeof(float)) { result.register.single_0 = ((left.register.single_0 > right.register.single_0) ? left.register.single_0 : right.register.single_0); result.register.single_1 = ((left.register.single_1 > right.register.single_1) ? left.register.single_1 : right.register.single_1); result.register.single_2 = ((left.register.single_2 > right.register.single_2) ? left.register.single_2 : right.register.single_2); result.register.single_3 = ((left.register.single_3 > right.register.single_3) ? left.register.single_3 : right.register.single_3); return result; } if (typeof(T) == typeof(double)) { result.register.double_0 = ((left.register.double_0 > right.register.double_0) ? left.register.double_0 : right.register.double_0); result.register.double_1 = ((left.register.double_1 > right.register.double_1) ? left.register.double_1 : right.register.double_1); return result; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [System.Runtime.CompilerServices.Intrinsic] internal static T DotProduct(Vector left, Vector right) { if (Vector.IsHardwareAccelerated) { T val = default(T); for (int i = 0; i < Count; i++) { val = ScalarAdd(val, ScalarMultiply(left[i], right[i])); } return val; } if (typeof(T) == typeof(byte)) { byte b = 0; b += (byte)(left.register.byte_0 * right.register.byte_0); b += (byte)(left.register.byte_1 * right.register.byte_1); b += (byte)(left.register.byte_2 * right.register.byte_2); b += (byte)(left.register.byte_3 * right.register.byte_3); b += (byte)(left.register.byte_4 * right.register.byte_4); b += (byte)(left.register.byte_5 * right.register.byte_5); b += (byte)(left.register.byte_6 * right.register.byte_6); b += (byte)(left.register.byte_7 * right.register.byte_7); b += (byte)(left.register.byte_8 * right.register.byte_8); b += (byte)(left.register.byte_9 * right.register.byte_9); b += (byte)(left.register.byte_10 * right.register.byte_10); b += (byte)(left.register.byte_11 * right.register.byte_11); b += (byte)(left.register.byte_12 * right.register.byte_12); b += (byte)(left.register.byte_13 * right.register.byte_13); b += (byte)(left.register.byte_14 * right.register.byte_14); b += (byte)(left.register.byte_15 * right.register.byte_15); return (T)(object)b; } if (typeof(T) == typeof(sbyte)) { sbyte b2 = 0; b2 += (sbyte)(left.register.sbyte_0 * right.register.sbyte_0); b2 += (sbyte)(left.register.sbyte_1 * right.register.sbyte_1); b2 += (sbyte)(left.register.sbyte_2 * right.register.sbyte_2); b2 += (sbyte)(left.register.sbyte_3 * right.register.sbyte_3); b2 += (sbyte)(left.register.sbyte_4 * right.register.sbyte_4); b2 += (sbyte)(left.register.sbyte_5 * right.register.sbyte_5); b2 += (sbyte)(left.register.sbyte_6 * right.register.sbyte_6); b2 += (sbyte)(left.register.sbyte_7 * right.register.sbyte_7); b2 += (sbyte)(left.register.sbyte_8 * right.register.sbyte_8); b2 += (sbyte)(left.register.sbyte_9 * right.register.sbyte_9); b2 += (sbyte)(left.register.sbyte_10 * right.register.sbyte_10); b2 += (sbyte)(left.register.sbyte_11 * right.register.sbyte_11); b2 += (sbyte)(left.register.sbyte_12 * right.register.sbyte_12); b2 += (sbyte)(left.register.sbyte_13 * right.register.sbyte_13); b2 += (sbyte)(left.register.sbyte_14 * right.register.sbyte_14); b2 += (sbyte)(left.register.sbyte_15 * right.register.sbyte_15); return (T)(object)b2; } if (typeof(T) == typeof(ushort)) { ushort num = 0; num += (ushort)(left.register.uint16_0 * right.register.uint16_0); num += (ushort)(left.register.uint16_1 * right.register.uint16_1); num += (ushort)(left.register.uint16_2 * right.register.uint16_2); num += (ushort)(left.register.uint16_3 * right.register.uint16_3); num += (ushort)(left.register.uint16_4 * right.register.uint16_4); num += (ushort)(left.register.uint16_5 * right.register.uint16_5); num += (ushort)(left.register.uint16_6 * right.register.uint16_6); num += (ushort)(left.register.uint16_7 * right.register.uint16_7); return (T)(object)num; } if (typeof(T) == typeof(short)) { short num2 = 0; num2 += (short)(left.register.int16_0 * right.register.int16_0); num2 += (short)(left.register.int16_1 * right.register.int16_1); num2 += (short)(left.register.int16_2 * right.register.int16_2); num2 += (short)(left.register.int16_3 * right.register.int16_3); num2 += (short)(left.register.int16_4 * right.register.int16_4); num2 += (short)(left.register.int16_5 * right.register.int16_5); num2 += (short)(left.register.int16_6 * right.register.int16_6); num2 += (short)(left.register.int16_7 * right.register.int16_7); return (T)(object)num2; } if (typeof(T) == typeof(uint)) { uint num3 = 0u; num3 += left.register.uint32_0 * right.register.uint32_0; num3 += left.register.uint32_1 * right.register.uint32_1; num3 += left.register.uint32_2 * right.register.uint32_2; num3 += left.register.uint32_3 * right.register.uint32_3; return (T)(object)num3; } if (typeof(T) == typeof(int)) { int num4 = 0; num4 += left.register.int32_0 * right.register.int32_0; num4 += left.register.int32_1 * right.register.int32_1; num4 += left.register.int32_2 * right.register.int32_2; num4 += left.register.int32_3 * right.register.int32_3; return (T)(object)num4; } if (typeof(T) == typeof(ulong)) { ulong num5 = 0uL; num5 += left.register.uint64_0 * right.register.uint64_0; num5 += left.register.uint64_1 * right.register.uint64_1; return (T)(object)num5; } if (typeof(T) == typeof(long)) { long num6 = 0L; num6 += left.register.int64_0 * right.register.int64_0; num6 += left.register.int64_1 * right.register.int64_1; return (T)(object)num6; } if (typeof(T) == typeof(float)) { float num7 = 0f; num7 += left.register.single_0 * right.register.single_0; num7 += left.register.single_1 * right.register.single_1; num7 += left.register.single_2 * right.register.single_2; num7 += left.register.single_3 * right.register.single_3; return (T)(object)num7; } if (typeof(T) == typeof(double)) { double num8 = 0.0; num8 += left.register.double_0 * right.register.double_0; num8 += left.register.double_1 * right.register.double_1; return (T)(object)num8; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [System.Runtime.CompilerServices.Intrinsic] internal unsafe static Vector SquareRoot(Vector value) { if (Vector.IsHardwareAccelerated) { if (typeof(T) == typeof(byte)) { byte* ptr = stackalloc byte[(int)(uint)Count]; for (int i = 0; i < Count; i++) { ptr[i] = (byte)Math.Sqrt((int)(byte)(object)value[i]); } return new Vector(ptr); } if (typeof(T) == typeof(sbyte)) { sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count]; for (int j = 0; j < Count; j++) { ptr2[j] = (sbyte)Math.Sqrt((sbyte)(object)value[j]); } return new Vector(ptr2); } if (typeof(T) == typeof(ushort)) { ushort* ptr3 = stackalloc ushort[Count]; for (int k = 0; k < Count; k++) { ptr3[k] = (ushort)Math.Sqrt((int)(ushort)(object)value[k]); } return new Vector(ptr3); } if (typeof(T) == typeof(short)) { short* ptr4 = stackalloc short[Count]; for (int l = 0; l < Count; l++) { ptr4[l] = (short)Math.Sqrt((short)(object)value[l]); } return new Vector(ptr4); } if (typeof(T) == typeof(uint)) { uint* ptr5 = stackalloc uint[Count]; for (int m = 0; m < Count; m++) { ptr5[m] = (uint)Math.Sqrt((uint)(object)value[m]); } return new Vector(ptr5); } if (typeof(T) == typeof(int)) { int* ptr6 = stackalloc int[Count]; for (int n = 0; n < Count; n++) { ptr6[n] = (int)Math.Sqrt((int)(object)value[n]); } return new Vector(ptr6); } if (typeof(T) == typeof(ulong)) { ulong* ptr7 = stackalloc ulong[Count]; for (int num = 0; num < Count; num++) { ptr7[num] = (ulong)Math.Sqrt((ulong)(object)value[num]); } return new Vector(ptr7); } if (typeof(T) == typeof(long)) { long* ptr8 = stackalloc long[Count]; for (int num2 = 0; num2 < Count; num2++) { ptr8[num2] = (long)Math.Sqrt((long)(object)value[num2]); } return new Vector(ptr8); } if (typeof(T) == typeof(float)) { float* ptr9 = stackalloc float[Count]; for (int num3 = 0; num3 < Count; num3++) { ptr9[num3] = (float)Math.Sqrt((float)(object)value[num3]); } return new Vector(ptr9); } if (typeof(T) == typeof(double)) { double* ptr10 = stackalloc double[Count]; for (int num4 = 0; num4 < Count; num4++) { ptr10[num4] = Math.Sqrt((double)(object)value[num4]); } return new Vector(ptr10); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } if (typeof(T) == typeof(byte)) { value.register.byte_0 = (byte)Math.Sqrt((int)value.register.byte_0); value.register.byte_1 = (byte)Math.Sqrt((int)value.register.byte_1); value.register.byte_2 = (byte)Math.Sqrt((int)value.register.byte_2); value.register.byte_3 = (byte)Math.Sqrt((int)value.register.byte_3); value.register.byte_4 = (byte)Math.Sqrt((int)value.register.byte_4); value.register.byte_5 = (byte)Math.Sqrt((int)value.register.byte_5); value.register.byte_6 = (byte)Math.Sqrt((int)value.register.byte_6); value.register.byte_7 = (byte)Math.Sqrt((int)value.register.byte_7); value.register.byte_8 = (byte)Math.Sqrt((int)value.register.byte_8); value.register.byte_9 = (byte)Math.Sqrt((int)value.register.byte_9); value.register.byte_10 = (byte)Math.Sqrt((int)value.register.byte_10); value.register.byte_11 = (byte)Math.Sqrt((int)value.register.byte_11); value.register.byte_12 = (byte)Math.Sqrt((int)value.register.byte_12); value.register.byte_13 = (byte)Math.Sqrt((int)value.register.byte_13); value.register.byte_14 = (byte)Math.Sqrt((int)value.register.byte_14); value.register.byte_15 = (byte)Math.Sqrt((int)value.register.byte_15); return value; } if (typeof(T) == typeof(sbyte)) { value.register.sbyte_0 = (sbyte)Math.Sqrt(value.register.sbyte_0); value.register.sbyte_1 = (sbyte)Math.Sqrt(value.register.sbyte_1); value.register.sbyte_2 = (sbyte)Math.Sqrt(value.register.sbyte_2); value.register.sbyte_3 = (sbyte)Math.Sqrt(value.register.sbyte_3); value.register.sbyte_4 = (sbyte)Math.Sqrt(value.register.sbyte_4); value.register.sbyte_5 = (sbyte)Math.Sqrt(value.register.sbyte_5); value.register.sbyte_6 = (sbyte)Math.Sqrt(value.register.sbyte_6); value.register.sbyte_7 = (sbyte)Math.Sqrt(value.register.sbyte_7); value.register.sbyte_8 = (sbyte)Math.Sqrt(value.register.sbyte_8); value.register.sbyte_9 = (sbyte)Math.Sqrt(value.register.sbyte_9); value.register.sbyte_10 = (sbyte)Math.Sqrt(value.register.sbyte_10); value.register.sbyte_11 = (sbyte)Math.Sqrt(value.register.sbyte_11); value.register.sbyte_12 = (sbyte)Math.Sqrt(value.register.sbyte_12); value.register.sbyte_13 = (sbyte)Math.Sqrt(value.register.sbyte_13); value.register.sbyte_14 = (sbyte)Math.Sqrt(value.register.sbyte_14); value.register.sbyte_15 = (sbyte)Math.Sqrt(value.register.sbyte_15); return value; } if (typeof(T) == typeof(ushort)) { value.register.uint16_0 = (ushort)Math.Sqrt((int)value.register.uint16_0); value.register.uint16_1 = (ushort)Math.Sqrt((int)value.register.uint16_1); value.register.uint16_2 = (ushort)Math.Sqrt((int)value.register.uint16_2); value.register.uint16_3 = (ushort)Math.Sqrt((int)value.register.uint16_3); value.register.uint16_4 = (ushort)Math.Sqrt((int)value.register.uint16_4); value.register.uint16_5 = (ushort)Math.Sqrt((int)value.register.uint16_5); value.register.uint16_6 = (ushort)Math.Sqrt((int)value.register.uint16_6); value.register.uint16_7 = (ushort)Math.Sqrt((int)value.register.uint16_7); return value; } if (typeof(T) == typeof(short)) { value.register.int16_0 = (short)Math.Sqrt(value.register.int16_0); value.register.int16_1 = (short)Math.Sqrt(value.register.int16_1); value.register.int16_2 = (short)Math.Sqrt(value.register.int16_2); value.register.int16_3 = (short)Math.Sqrt(value.register.int16_3); value.register.int16_4 = (short)Math.Sqrt(value.register.int16_4); value.register.int16_5 = (short)Math.Sqrt(value.register.int16_5); value.register.int16_6 = (short)Math.Sqrt(value.register.int16_6); value.register.int16_7 = (short)Math.Sqrt(value.register.int16_7); return value; } if (typeof(T) == typeof(uint)) { value.register.uint32_0 = (uint)Math.Sqrt(value.register.uint32_0); value.register.uint32_1 = (uint)Math.Sqrt(value.register.uint32_1); value.register.uint32_2 = (uint)Math.Sqrt(value.register.uint32_2); value.register.uint32_3 = (uint)Math.Sqrt(value.register.uint32_3); return value; } if (typeof(T) == typeof(int)) { value.register.int32_0 = (int)Math.Sqrt(value.register.int32_0); value.register.int32_1 = (int)Math.Sqrt(value.register.int32_1); value.register.int32_2 = (int)Math.Sqrt(value.register.int32_2); value.register.int32_3 = (int)Math.Sqrt(value.register.int32_3); return value; } if (typeof(T) == typeof(ulong)) { value.register.uint64_0 = (ulong)Math.Sqrt(value.register.uint64_0); value.register.uint64_1 = (ulong)Math.Sqrt(value.register.uint64_1); return value; } if (typeof(T) == typeof(long)) { value.register.int64_0 = (long)Math.Sqrt(value.register.int64_0); value.register.int64_1 = (long)Math.Sqrt(value.register.int64_1); return value; } if (typeof(T) == typeof(float)) { value.register.single_0 = (float)Math.Sqrt(value.register.single_0); value.register.single_1 = (float)Math.Sqrt(value.register.single_1); value.register.single_2 = (float)Math.Sqrt(value.register.single_2); value.register.single_3 = (float)Math.Sqrt(value.register.single_3); return value; } if (typeof(T) == typeof(double)) { value.register.double_0 = Math.Sqrt(value.register.double_0); value.register.double_1 = Math.Sqrt(value.register.double_1); return value; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool ScalarEquals(T left, T right) { if (typeof(T) == typeof(byte)) { return (byte)(object)left == (byte)(object)right; } if (typeof(T) == typeof(sbyte)) { return (sbyte)(object)left == (sbyte)(object)right; } if (typeof(T) == typeof(ushort)) { return (ushort)(object)left == (ushort)(object)right; } if (typeof(T) == typeof(short)) { return (short)(object)left == (short)(object)right; } if (typeof(T) == typeof(uint)) { return (uint)(object)left == (uint)(object)right; } if (typeof(T) == typeof(int)) { return (int)(object)left == (int)(object)right; } if (typeof(T) == typeof(ulong)) { return (ulong)(object)left == (ulong)(object)right; } if (typeof(T) == typeof(long)) { return (long)(object)left == (long)(object)right; } if (typeof(T) == typeof(float)) { return (float)(object)left == (float)(object)right; } if (typeof(T) == typeof(double)) { return (double)(object)left == (double)(object)right; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool ScalarLessThan(T left, T right) { if (typeof(T) == typeof(byte)) { return (byte)(object)left < (byte)(object)right; } if (typeof(T) == typeof(sbyte)) { return (sbyte)(object)left < (sbyte)(object)right; } if (typeof(T) == typeof(ushort)) { return (ushort)(object)left < (ushort)(object)right; } if (typeof(T) == typeof(short)) { return (short)(object)left < (short)(object)right; } if (typeof(T) == typeof(uint)) { return (uint)(object)left < (uint)(object)right; } if (typeof(T) == typeof(int)) { return (int)(object)left < (int)(object)right; } if (typeof(T) == typeof(ulong)) { return (ulong)(object)left < (ulong)(object)right; } if (typeof(T) == typeof(long)) { return (long)(object)left < (long)(object)right; } if (typeof(T) == typeof(float)) { return (float)(object)left < (float)(object)right; } if (typeof(T) == typeof(double)) { return (double)(object)left < (double)(object)right; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool ScalarGreaterThan(T left, T right) { if (typeof(T) == typeof(byte)) { return (byte)(object)left > (byte)(object)right; } if (typeof(T) == typeof(sbyte)) { return (sbyte)(object)left > (sbyte)(object)right; } if (typeof(T) == typeof(ushort)) { return (ushort)(object)left > (ushort)(object)right; } if (typeof(T) == typeof(short)) { return (short)(object)left > (short)(object)right; } if (typeof(T) == typeof(uint)) { return (uint)(object)left > (uint)(object)right; } if (typeof(T) == typeof(int)) { return (int)(object)left > (int)(object)right; } if (typeof(T) == typeof(ulong)) { return (ulong)(object)left > (ulong)(object)right; } if (typeof(T) == typeof(long)) { return (long)(object)left > (long)(object)right; } if (typeof(T) == typeof(float)) { return (float)(object)left > (float)(object)right; } if (typeof(T) == typeof(double)) { return (double)(object)left > (double)(object)right; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T ScalarAdd(T left, T right) { if (typeof(T) == typeof(byte)) { return (T)(object)(byte)((byte)(object)left + (byte)(object)right); } if (typeof(T) == typeof(sbyte)) { return (T)(object)(sbyte)((sbyte)(object)left + (sbyte)(object)right); } if (typeof(T) == typeof(ushort)) { return (T)(object)(ushort)((ushort)(object)left + (ushort)(object)right); } if (typeof(T) == typeof(short)) { return (T)(object)(short)((short)(object)left + (short)(object)right); } if (typeof(T) == typeof(uint)) { return (T)(object)((uint)(object)left + (uint)(object)right); } if (typeof(T) == typeof(int)) { return (T)(object)((int)(object)left + (int)(object)right); } if (typeof(T) == typeof(ulong)) { return (T)(object)((ulong)(object)left + (ulong)(object)right); } if (typeof(T) == typeof(long)) { return (T)(object)((long)(object)left + (long)(object)right); } if (typeof(T) == typeof(float)) { return (T)(object)((float)(object)left + (float)(object)right); } if (typeof(T) == typeof(double)) { return (T)(object)((double)(object)left + (double)(object)right); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T ScalarSubtract(T left, T right) { if (typeof(T) == typeof(byte)) { return (T)(object)(byte)((byte)(object)left - (byte)(object)right); } if (typeof(T) == typeof(sbyte)) { return (T)(object)(sbyte)((sbyte)(object)left - (sbyte)(object)right); } if (typeof(T) == typeof(ushort)) { return (T)(object)(ushort)((ushort)(object)left - (ushort)(object)right); } if (typeof(T) == typeof(short)) { return (T)(object)(short)((short)(object)left - (short)(object)right); } if (typeof(T) == typeof(uint)) { return (T)(object)((uint)(object)left - (uint)(object)right); } if (typeof(T) == typeof(int)) { return (T)(object)((int)(object)left - (int)(object)right); } if (typeof(T) == typeof(ulong)) { return (T)(object)((ulong)(object)left - (ulong)(object)right); } if (typeof(T) == typeof(long)) { return (T)(object)((long)(object)left - (long)(object)right); } if (typeof(T) == typeof(float)) { return (T)(object)((float)(object)left - (float)(object)right); } if (typeof(T) == typeof(double)) { return (T)(object)((double)(object)left - (double)(object)right); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T ScalarMultiply(T left, T right) { if (typeof(T) == typeof(byte)) { return (T)(object)(byte)((byte)(object)left * (byte)(object)right); } if (typeof(T) == typeof(sbyte)) { return (T)(object)(sbyte)((sbyte)(object)left * (sbyte)(object)right); } if (typeof(T) == typeof(ushort)) { return (T)(object)(ushort)((ushort)(object)left * (ushort)(object)right); } if (typeof(T) == typeof(short)) { return (T)(object)(short)((short)(object)left * (short)(object)right); } if (typeof(T) == typeof(uint)) { return (T)(object)((uint)(object)left * (uint)(object)right); } if (typeof(T) == typeof(int)) { return (T)(object)((int)(object)left * (int)(object)right); } if (typeof(T) == typeof(ulong)) { return (T)(object)((ulong)(object)left * (ulong)(object)right); } if (typeof(T) == typeof(long)) { return (T)(object)((long)(object)left * (long)(object)right); } if (typeof(T) == typeof(float)) { return (T)(object)((float)(object)left * (float)(object)right); } if (typeof(T) == typeof(double)) { return (T)(object)((double)(object)left * (double)(object)right); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T ScalarDivide(T left, T right) { if (typeof(T) == typeof(byte)) { return (T)(object)(byte)((byte)(object)left / (byte)(object)right); } if (typeof(T) == typeof(sbyte)) { return (T)(object)(sbyte)((sbyte)(object)left / (sbyte)(object)right); } if (typeof(T) == typeof(ushort)) { return (T)(object)(ushort)((ushort)(object)left / (ushort)(object)right); } if (typeof(T) == typeof(short)) { return (T)(object)(short)((short)(object)left / (short)(object)right); } if (typeof(T) == typeof(uint)) { return (T)(object)((uint)(object)left / (uint)(object)right); } if (typeof(T) == typeof(int)) { return (T)(object)((int)(object)left / (int)(object)right); } if (typeof(T) == typeof(ulong)) { return (T)(object)((ulong)(object)left / (ulong)(object)right); } if (typeof(T) == typeof(long)) { return (T)(object)((long)(object)left / (long)(object)right); } if (typeof(T) == typeof(float)) { return (T)(object)((float)(object)left / (float)(object)right); } if (typeof(T) == typeof(double)) { return (T)(object)((double)(object)left / (double)(object)right); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T GetOneValue() { if (typeof(T) == typeof(byte)) { byte b = 1; return (T)(object)b; } if (typeof(T) == typeof(sbyte)) { sbyte b2 = 1; return (T)(object)b2; } if (typeof(T) == typeof(ushort)) { ushort num = 1; return (T)(object)num; } if (typeof(T) == typeof(short)) { short num2 = 1; return (T)(object)num2; } if (typeof(T) == typeof(uint)) { uint num3 = 1u; return (T)(object)num3; } if (typeof(T) == typeof(int)) { int num4 = 1; return (T)(object)num4; } if (typeof(T) == typeof(ulong)) { ulong num5 = 1uL; return (T)(object)num5; } if (typeof(T) == typeof(long)) { long num6 = 1L; return (T)(object)num6; } if (typeof(T) == typeof(float)) { float num7 = 1f; return (T)(object)num7; } if (typeof(T) == typeof(double)) { double num8 = 1.0; return (T)(object)num8; } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T GetAllBitsSetValue() { if (typeof(T) == typeof(byte)) { return (T)(object)ConstantHelper.GetByteWithAllBitsSet(); } if (typeof(T) == typeof(sbyte)) { return (T)(object)ConstantHelper.GetSByteWithAllBitsSet(); } if (typeof(T) == typeof(ushort)) { return (T)(object)ConstantHelper.GetUInt16WithAllBitsSet(); } if (typeof(T) == typeof(short)) { return (T)(object)ConstantHelper.GetInt16WithAllBitsSet(); } if (typeof(T) == typeof(uint)) { return (T)(object)ConstantHelper.GetUInt32WithAllBitsSet(); } if (typeof(T) == typeof(int)) { return (T)(object)ConstantHelper.GetInt32WithAllBitsSet(); } if (typeof(T) == typeof(ulong)) { return (T)(object)ConstantHelper.GetUInt64WithAllBitsSet(); } if (typeof(T) == typeof(long)) { return (T)(object)ConstantHelper.GetInt64WithAllBitsSet(); } if (typeof(T) == typeof(float)) { return (T)(object)ConstantHelper.GetSingleWithAllBitsSet(); } if (typeof(T) == typeof(double)) { return (T)(object)ConstantHelper.GetDoubleWithAllBitsSet(); } throw new NotSupportedException(System.SR.Arg_TypeNotSupported); } } [System.Runtime.CompilerServices.Intrinsic] internal static class Vector { public static bool IsHardwareAccelerated { [System.Runtime.CompilerServices.Intrinsic] get { return false; } } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; ushort* ptr = stackalloc ushort[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } ushort* ptr2 = stackalloc ushort[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; uint* ptr = stackalloc uint[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } uint* ptr2 = stackalloc uint[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; ulong* ptr = stackalloc ulong[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } ulong* ptr2 = stackalloc ulong[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; short* ptr = stackalloc short[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } short* ptr2 = stackalloc short[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; int* ptr = stackalloc int[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } int* ptr2 = stackalloc int[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; long* ptr = stackalloc long[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } long* ptr2 = stackalloc long[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static void Widen(Vector source, out Vector low, out Vector high) { int count = Vector.Count; double* ptr = stackalloc double[count / 2]; for (int i = 0; i < count / 2; i++) { ptr[i] = source[i]; } double* ptr2 = stackalloc double[count / 2]; for (int j = 0; j < count / 2; j++) { ptr2[j] = source[j + count / 2]; } low = new Vector(ptr); high = new Vector(ptr2); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; byte* ptr = stackalloc byte[(int)(uint)count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (byte)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (byte)high[j]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; ushort* ptr = stackalloc ushort[count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (ushort)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (ushort)high[j]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; uint* ptr = stackalloc uint[count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (uint)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (uint)high[j]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; sbyte* ptr = stackalloc sbyte[(int)(uint)count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (sbyte)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (sbyte)high[j]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; short* ptr = stackalloc short[count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (short)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (short)high[j]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; int* ptr = stackalloc int[count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (int)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (int)high[j]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector Narrow(Vector low, Vector high) { int count = Vector.Count; float* ptr = stackalloc float[count]; for (int i = 0; i < count / 2; i++) { ptr[i] = (float)low[i]; } for (int j = 0; j < count / 2; j++) { ptr[j + count / 2] = (float)high[j]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToSingle(Vector value) { int count = Vector.Count; float* ptr = stackalloc float[count]; for (int i = 0; i < count; i++) { ptr[i] = value[i]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToSingle(Vector value) { int count = Vector.Count; float* ptr = stackalloc float[count]; for (int i = 0; i < count; i++) { ptr[i] = value[i]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToDouble(Vector value) { int count = Vector.Count; double* ptr = stackalloc double[count]; for (int i = 0; i < count; i++) { ptr[i] = value[i]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToDouble(Vector value) { int count = Vector.Count; double* ptr = stackalloc double[count]; for (int i = 0; i < count; i++) { ptr[i] = value[i]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToInt32(Vector value) { int count = Vector.Count; int* ptr = stackalloc int[count]; for (int i = 0; i < count; i++) { ptr[i] = (int)value[i]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToUInt32(Vector value) { int count = Vector.Count; uint* ptr = stackalloc uint[count]; for (int i = 0; i < count; i++) { ptr[i] = (uint)value[i]; } return new Vector(ptr); } [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToInt64(Vector value) { int count = Vector.Count; long* ptr = stackalloc long[count]; for (int i = 0; i < count; i++) { ptr[i] = (long)value[i]; } return new Vector(ptr); } [CLSCompliant(false)] [System.Runtime.CompilerServices.Intrinsic] public unsafe static Vector ConvertToUInt64(Vector value) { int count = Vector.Count; ulong* ptr = stackalloc ulong[count]; for (int i = 0; i < count; i++) { ptr[i] = (ulong)value[i]; } return new Vector(ptr); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) { return Vector.ConditionalSelect((Vector)condition, left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) { return Vector.ConditionalSelect((Vector)condition, left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) where T : struct { return Vector.ConditionalSelect(condition, left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) where T : struct { return Vector.Equals(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return (Vector)Vector.Equals(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return Vector.Equals(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return (Vector)Vector.Equals(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return Vector.Equals(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool EqualsAll(Vector left, Vector right) where T : struct { return left == right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool EqualsAny(Vector left, Vector right) where T : struct { return !Vector.Equals(left, right).Equals(Vector.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) where T : struct { return Vector.LessThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return (Vector)Vector.LessThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return Vector.LessThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return (Vector)Vector.LessThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return Vector.LessThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool LessThanAll(Vector left, Vector right) where T : struct { return ((Vector)Vector.LessThan(left, right)).Equals(Vector.AllOnes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool LessThanAny(Vector left, Vector right) where T : struct { return !((Vector)Vector.LessThan(left, right)).Equals(Vector.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) where T : struct { return Vector.LessThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return (Vector)Vector.LessThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return Vector.LessThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return Vector.LessThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return (Vector)Vector.LessThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool LessThanOrEqualAll(Vector left, Vector right) where T : struct { return ((Vector)Vector.LessThanOrEqual(left, right)).Equals(Vector.AllOnes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool LessThanOrEqualAny(Vector left, Vector right) where T : struct { return !((Vector)Vector.LessThanOrEqual(left, right)).Equals(Vector.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) where T : struct { return Vector.GreaterThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return (Vector)Vector.GreaterThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return Vector.GreaterThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return (Vector)Vector.GreaterThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return Vector.GreaterThan(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanAll(Vector left, Vector right) where T : struct { return ((Vector)Vector.GreaterThan(left, right)).Equals(Vector.AllOnes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanAny(Vector left, Vector right) where T : struct { return !((Vector)Vector.GreaterThan(left, right)).Equals(Vector.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) where T : struct { return Vector.GreaterThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return (Vector)Vector.GreaterThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return Vector.GreaterThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return Vector.GreaterThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return (Vector)Vector.GreaterThanOrEqual(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanOrEqualAll(Vector left, Vector right) where T : struct { return ((Vector)Vector.GreaterThanOrEqual(left, right)).Equals(Vector.AllOnes); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanOrEqualAny(Vector left, Vector right) where T : struct { return !((Vector)Vector.GreaterThanOrEqual(left, right)).Equals(Vector.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Abs(Vector value) where T : struct { return Vector.Abs(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Min(Vector left, Vector right) where T : struct { return Vector.Min(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Max(Vector left, Vector right) where T : struct { return Vector.Max(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Dot(Vector left, Vector right) where T : struct { return Vector.DotProduct(left, right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector SquareRoot(Vector value) where T : struct { return Vector.SquareRoot(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Add(Vector left, Vector right) where T : struct { return left + right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Subtract(Vector left, Vector right) where T : struct { return left - right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(Vector left, Vector right) where T : struct { return left * right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(Vector left, T right) where T : struct { return left * right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(T left, Vector right) where T : struct { return left * right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Divide(Vector left, Vector right) where T : struct { return left / right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Negate(Vector value) where T : struct { return -value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector BitwiseAnd(Vector left, Vector right) where T : struct { return left & right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector BitwiseOr(Vector left, Vector right) where T : struct { return left | right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector OnesComplement(Vector value) where T : struct { return ~value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Xor(Vector left, Vector right) where T : struct { return left ^ right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AndNot(Vector left, Vector right) where T : struct { return left & ~right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorByte(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static Vector AsVectorSByte(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static Vector AsVectorUInt16(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt16(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static Vector AsVectorUInt32(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt32(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static Vector AsVectorUInt64(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt64(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorSingle(Vector value) where T : struct { return (Vector)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorDouble(Vector value) where T : struct { return (Vector)value; } } } namespace System.Numerics.Hashing { internal static class HashHelpers { public static readonly int RandomSeed = Guid.NewGuid().GetHashCode(); public static int Combine(int h1, int h2) { uint num = (uint)((h1 << 5) | (h1 >>> 27)); return ((int)num + h1) ^ h2; } } } namespace System.Runtime.CompilerServices { internal static class Unsafe { [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static T Read(void* source) { return Unsafe.Read(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static T ReadUnaligned(void* source) { return Unsafe.ReadUnaligned(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static T ReadUnaligned(ref byte source) { return Unsafe.ReadUnaligned(ref source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Write(void* destination, T value) { Unsafe.Write(destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void WriteUnaligned(void* destination, T value) { Unsafe.WriteUnaligned(destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void WriteUnaligned(ref byte destination, T value) { Unsafe.WriteUnaligned(ref destination, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Copy(void* destination, ref T source) { Unsafe.Write(destination, source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void Copy(ref T destination, void* source) { destination = Unsafe.Read(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* AsPointer(ref T value) { return Unsafe.AsPointer(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void SkipInit(out T value) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static int SizeOf() { return Unsafe.SizeOf(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void CopyBlock(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(destination, source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void CopyBlock(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlock(ref destination, ref source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(destination, source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount) { // IL cpblk instruction Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void InitBlock(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlock(ref startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { // IL initblk instruction Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static T As(object o) where T : class { return (T)o; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static ref T AsRef(void* source) { return ref *(T*)source; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T AsRef(in T source) { return ref source; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref TTo As(ref TFrom source) { return ref Unsafe.As(ref source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Unbox(object box) where T : struct { return ref (T)box; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Add(ref T source, int elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* Add(void* source, int elementOffset) { return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Add(ref T source, IntPtr elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T Add(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset) { return ref Unsafe.Add(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T AddByteOffset(ref T source, IntPtr byteOffset) { return ref Unsafe.AddByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T AddByteOffset(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset) { return ref Unsafe.AddByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Subtract(ref T source, int elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static void* Subtract(void* source, int elementOffset) { return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T Subtract(ref T source, IntPtr elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T Subtract(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset) { return ref Unsafe.Subtract(ref source, elementOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static ref T SubtractByteOffset(ref T source, IntPtr byteOffset) { return ref Unsafe.SubtractByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T SubtractByteOffset(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset) { return ref Unsafe.SubtractByteOffset(ref source, byteOffset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static IntPtr ByteOffset(ref T origin, ref T target) { return Unsafe.ByteOffset(target: ref target, origin: ref origin); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool AreSame(ref T left, ref T right) { return Unsafe.AreSame(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool IsAddressGreaterThan(ref T left, ref T right) { return Unsafe.IsAddressGreaterThan(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public static bool IsAddressLessThan(ref T left, ref T right) { return Unsafe.IsAddressLessThan(ref left, ref right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static bool IsNullRef(ref T source) { return Unsafe.AsPointer(ref source) == null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.Versioning.NonVersionable] public unsafe static ref T NullRef() { return ref *(T*)null; } } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class NonVersionableAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [Embedded] [CompilerGenerated] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] A_0) { TransformFlags = A_0; } } }