Tools.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Runtime.CompilerServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Threading.Tasks.Dataflow;
  9. using Avalonia.Controls;
  10. using MessagePack;
  11. using MessagePack.Resolvers;
  12. using ShakerApp.Models;
  13. using ShakerApp.ViewModels;
  14. namespace ShakerApp.Tools
  15. {
  16. public static class Tools
  17. {
  18. public static void CalcStatistics(ref StatisticsViewModel model,ref float value,uint len)
  19. {
  20. }
  21. public static string GetUnit(this Models.TimeDomainType type)
  22. {
  23. return (type.GetType()?
  24. .GetField(type.ToString())?
  25. .GetCustomAttributes<TimeDomainUnitAttribute>()
  26. .FirstOrDefault())?.Unit ?? "";
  27. }
  28. private static MessagePackSerializerOptions options = TypelessContractlessStandardResolver.Options.WithOmitAssemblyVersion(true);
  29. public static byte[] GetBytes<T>(this T value)
  30. {
  31. return MessagePack.MessagePackSerializer.Serialize(value,options);
  32. }
  33. public static byte[] Serialize(Type type,object? value)
  34. {
  35. return MessagePack.MessagePackSerializer.Serialize(type, value, options);
  36. }
  37. public static object? Deserialize(Type type, ReadOnlyMemory<byte> bytes)
  38. {
  39. try
  40. {
  41. return MessagePack.MessagePackSerializer.Deserialize(type, bytes, options);
  42. }
  43. catch
  44. {
  45. return Activator.CreateInstance(type);
  46. }
  47. }
  48. public static T GetValue<T>(this byte[] data)
  49. {
  50. return MessagePackSerializer.Deserialize<T>(data,options);
  51. }
  52. public static T? ReadConfig<T>(this string configPath)
  53. {
  54. try
  55. {
  56. return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(System.IO.File.ReadAllText(configPath));
  57. }
  58. catch
  59. {
  60. }
  61. return default;
  62. }
  63. public static float CalcTHD(ref float value, uint len, uint highestharmonic = 7)
  64. {
  65. if (len <= 1 || highestharmonic <= 1) return 0;
  66. float[] real = new float[len];
  67. float[] img = new float[len];
  68. Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref value), len*(uint)Unsafe.SizeOf<float>());
  69. Shaker.Models.Tools.Tools.Calc.FFT.FFT(real, img);
  70. Shaker.Models.Tools.Tools.Calc.Multiply.Multiply(ref real[0], ref real[0], len);
  71. Shaker.Models.Tools.Tools.Calc.Multiply.Multiply(ref img[0], ref img[0], len);
  72. Shaker.Models.Tools.Tools.Calc.Add.Add(ref real[0], ref img[0], len);
  73. Shaker.Models.Tools.Tools.Calc.Sqrt.Sqrt(ref real[0], len);
  74. var peaks = FindPeaks(ref real[0], len);
  75. if (peaks.Count == 0) return 0;
  76. var valueindex = peaks.FindIndex(x => x.Value == peaks.Max(y => y.Value));
  77. float maxv = peaks[valueindex].Value;
  78. int maxvindex = peaks[valueindex].Index;
  79. float harmonicv = 0;
  80. for (int i = 0; i < highestharmonic - 1; i++)
  81. {
  82. int index = (i + 2) * maxvindex;
  83. if (index >= len - 1) break;
  84. harmonicv += real[index] * real[index];
  85. }
  86. harmonicv = MathF.Sqrt(harmonicv) / maxv;
  87. harmonicv = maxv == 0 ? 0 : harmonicv;
  88. return harmonicv;
  89. }
  90. public static double CalcTHD(ref double value, uint len, uint highestharmonic = 7)
  91. {
  92. if (len <= 1 || highestharmonic <= 1) return 0;
  93. double[] real = new double[len];
  94. double[] img = new double[len];
  95. Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref value), len*(uint)Unsafe.SizeOf<double>());
  96. Shaker.Models.Tools.Tools.Calc.FFT.FFT(real, img);
  97. Shaker.Models.Tools.Tools.Calc.Multiply.Multiply(ref real[0], ref real[0], len);
  98. Shaker.Models.Tools.Tools.Calc.Multiply.Multiply(ref img[0], ref img[0], len);
  99. Shaker.Models.Tools.Tools.Calc.Add.Add(ref real[0], ref img[0], len);
  100. Shaker.Models.Tools.Tools.Calc.Sqrt.Sqrt(ref real[0], len);
  101. double maxv = real.Max();
  102. int maxvindex = Array.IndexOf(real, maxv);
  103. double harmonicv = 0;
  104. for (int i = 0; i < highestharmonic - 1; i++)
  105. {
  106. int index = (i + 2) * maxvindex;
  107. if (index >= len - 1) break;
  108. harmonicv += real[index] * real[index];
  109. }
  110. harmonicv = Math.Sqrt(harmonicv) / maxv;
  111. harmonicv = maxv == 0 ? 0 : harmonicv;
  112. return harmonicv;
  113. }
  114. public static void SaveConfig<T>(this T? value,string configPath)
  115. {
  116. value = value ?? default;
  117. try
  118. {
  119. if (System.IO.File.Exists(configPath)) System.IO.File.Delete(configPath);
  120. System.IO.File.WriteAllText(configPath, Newtonsoft.Json.JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.Indented));
  121. }
  122. catch
  123. {
  124. }
  125. }
  126. public static List<(int Index,T Value)> FindPeaks<T>(ref T value,uint len,bool isrisingedge = true) where T :unmanaged
  127. {
  128. List<(int Index,T Value)> result = new List<(int Index,T Value)>();
  129. if (len <= 1) return result;
  130. int[] diff_v = new int[len - 1];
  131. for(int i=0;i<len-1;i++)
  132. {
  133. diff_v[i] = Comparer<T>.Default.Compare(Unsafe.Add(ref value,i),Unsafe.Add(ref value,i+1));
  134. }
  135. for (int i = diff_v.Length - 1; i >= 0; i--)
  136. {
  137. if (diff_v[i] == 0 && i == diff_v.Length - 1) diff_v[i] = 1;
  138. else if (diff_v[i] == 0)
  139. {
  140. if (diff_v[i + 1] >= 0) diff_v[i] = 1;
  141. else diff_v[i] = -1;
  142. }
  143. }
  144. for(int i=0;i<diff_v.Length-1;i++)
  145. {
  146. if (diff_v[i + 1] - diff_v[i] == (isrisingedge ?2: -2))
  147. {
  148. result.Add((i + 1, Unsafe.Add(ref value,i+1)));
  149. }
  150. }
  151. return result;
  152. }
  153. static Dictionary<RuntimeTypeHandle, Control> ViewCache = new Dictionary<RuntimeTypeHandle, Control>();
  154. public static T CreateView<T>(bool cache = true)where T:Control
  155. {
  156. if(cache)
  157. {
  158. Type t = typeof(T);
  159. if (ViewCache.TryGetValue(t.TypeHandle, out var control)) return (T)control;
  160. else
  161. {
  162. ViewCache[t.TypeHandle] = Activator.CreateInstance<T>();
  163. return (T)ViewCache[t.TypeHandle];
  164. }
  165. }
  166. else
  167. {
  168. return Activator.CreateInstance<T>();
  169. }
  170. }
  171. public static Control CreateView(Type type, bool cache = true)
  172. {
  173. if (cache)
  174. {
  175. if (ViewCache.TryGetValue(type.TypeHandle, out var control)) return control;
  176. else
  177. {
  178. ViewCache[type.TypeHandle] = (Control)Activator.CreateInstance(type)!;
  179. return ViewCache[type.TypeHandle];
  180. }
  181. }
  182. else
  183. {
  184. return (Control)Activator.CreateInstance(type)!;
  185. }
  186. }
  187. }
  188. }