using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using Avalonia.Controls; using MessagePack; using MessagePack.Resolvers; using ShakerApp.Models; using ShakerApp.ViewModels; namespace ShakerApp.Tools { public static class Tools { public static void CalcStatistics(ref StatisticsViewModel model,ref float value,uint len) { } public static string GetUnit(this Models.TimeDomainType type) { return (type.GetType()? .GetField(type.ToString())? .GetCustomAttributes() .FirstOrDefault())?.Unit ?? ""; } private static MessagePackSerializerOptions options = TypelessContractlessStandardResolver.Options.WithOmitAssemblyVersion(true); public static byte[] GetBytes(this T value) { return MessagePack.MessagePackSerializer.Serialize(value,options); } public static byte[] Serialize(Type type,object? value) { return MessagePack.MessagePackSerializer.Serialize(type, value, options); } public static object? Deserialize(Type type, ReadOnlyMemory bytes) { try { return MessagePack.MessagePackSerializer.Deserialize(type, bytes, options); } catch { return Activator.CreateInstance(type); } } public static T GetValue(this byte[] data) { return MessagePackSerializer.Deserialize(data,options); } public static T? ReadConfig(this string configPath) { try { return Newtonsoft.Json.JsonConvert.DeserializeObject(System.IO.File.ReadAllText(configPath)); } catch { } return default; } public static float CalcTHD(ref float value, uint len, uint highestharmonic = 7) { if (len <= 1 || highestharmonic <= 1) return 0; float[] real = new float[len]; float[] img = new float[len]; Unsafe.CopyBlock(ref Unsafe.As(ref real[0]), ref Unsafe.As(ref value), len*(uint)Unsafe.SizeOf()); MainViewModel.Default.Calc.FFT.FFT(real, img); MainViewModel.Default.Calc.Multiply.Multiply(ref real[0], ref real[0], len); MainViewModel.Default.Calc.Multiply.Multiply(ref img[0], ref img[0], len); MainViewModel.Default.Calc.Add.Add(ref real[0], ref img[0], len); MainViewModel.Default.Calc.Sqrt.Sqrt(ref real[0], len); var peaks = FindPeaks(ref real[0], len); if (peaks.Count == 0) return 0; var valueindex = peaks.FindIndex(x => x.Value == peaks.Max(y => y.Value)); float maxv = peaks[valueindex].Value; int maxvindex = peaks[valueindex].Index; float harmonicv = 0; for (int i = 0; i < highestharmonic - 1; i++) { int index = (i + 2) * maxvindex; if (index >= len - 1) break; harmonicv += real[index] * real[index]; } harmonicv = MathF.Sqrt(harmonicv) / maxv; harmonicv = maxv == 0 ? 0 : harmonicv; return harmonicv; } public static double CalcTHD(ref double value, uint len, uint highestharmonic = 7) { if (len <= 1 || highestharmonic <= 1) return 0; double[] real = new double[len]; double[] img = new double[len]; Unsafe.CopyBlock(ref Unsafe.As(ref real[0]), ref Unsafe.As(ref value), len*(uint)Unsafe.SizeOf()); MainViewModel.Default.Calc.FFT.FFT(real, img); MainViewModel.Default.Calc.Multiply.Multiply(ref real[0], ref real[0], len); MainViewModel.Default.Calc.Multiply.Multiply(ref img[0], ref img[0], len); MainViewModel.Default.Calc.Add.Add(ref real[0], ref img[0], len); MainViewModel.Default.Calc.Sqrt.Sqrt(ref real[0], len); double maxv = real.Max(); int maxvindex = Array.IndexOf(real, maxv); double harmonicv = 0; for (int i = 0; i < highestharmonic - 1; i++) { int index = (i + 2) * maxvindex; if (index >= len - 1) break; harmonicv += real[index] * real[index]; } harmonicv = Math.Sqrt(harmonicv) / maxv; harmonicv = maxv == 0 ? 0 : harmonicv; return harmonicv; } public static void SaveConfig(this T? value,string configPath) { value = value ?? default; try { if (System.IO.File.Exists(configPath)) System.IO.File.Delete(configPath); System.IO.File.WriteAllText(configPath, Newtonsoft.Json.JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.Indented)); } catch { } } public unsafe static List<(int Index,T Value)> FindPeaks(ref T value,uint len,bool isrisingedge = true) where T :unmanaged { List<(int Index,T Value)> result = new List<(int Index,T Value)>(); if (len <= 1) return result; int[] diff_v = new int[len - 1]; T* first = (T*)Unsafe.AsPointer(ref value); for(int i=0;i.Default.Compare(first[i], first[i + 1]); } for (int i = diff_v.Length - 1; i >= 0; i--) { if (diff_v[i] == 0 && i == diff_v.Length - 1) diff_v[i] = 1; else if (diff_v[i] == 0) { if (diff_v[i + 1] >= 0) diff_v[i] = 1; else diff_v[i] = -1; } } for(int i=0;i ViewCache = new Dictionary(); public static T CreateView(bool cache = true)where T:Control { if(cache) { Type t = typeof(T); if (ViewCache.TryGetValue(t.TypeHandle, out var control)) return (T)control; else { ViewCache[t.TypeHandle] = Activator.CreateInstance(); return (T)ViewCache[t.TypeHandle]; } } else { return Activator.CreateInstance(); } } public static Control CreateView(Type type, bool cache = true) { if (cache) { if (ViewCache.TryGetValue(type.TypeHandle, out var control)) return control; else { ViewCache[type.TypeHandle] = (Control)Activator.CreateInstance(type)!; return ViewCache[type.TypeHandle]; } } else { return (Control)Activator.CreateInstance(type)!; } } } }