Tools.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. MainViewModel.Default.Calc.FFT.FFT(real, img);
  70. MainViewModel.Default.Calc.Multiply.Multiply(ref real[0], ref real[0], len);
  71. MainViewModel.Default.Calc.Multiply.Multiply(ref img[0], ref img[0], len);
  72. MainViewModel.Default.Calc.Add.Add(ref real[0], ref img[0], len);
  73. MainViewModel.Default.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. MainViewModel.Default.Calc.FFT.FFT(real, img);
  97. MainViewModel.Default.Calc.Multiply.Multiply(ref real[0], ref real[0], len);
  98. MainViewModel.Default.Calc.Multiply.Multiply(ref img[0], ref img[0], len);
  99. MainViewModel.Default.Calc.Add.Add(ref real[0], ref img[0], len);
  100. MainViewModel.Default.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 unsafe 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. T* first = (T*)Unsafe.AsPointer(ref value);
  132. for(int i=0;i<len-1;i++)
  133. {
  134. diff_v[i] = Comparer<T>.Default.Compare(first[i], first[i + 1]);
  135. }
  136. for (int i = diff_v.Length - 1; i >= 0; i--)
  137. {
  138. if (diff_v[i] == 0 && i == diff_v.Length - 1) diff_v[i] = 1;
  139. else if (diff_v[i] == 0)
  140. {
  141. if (diff_v[i + 1] >= 0) diff_v[i] = 1;
  142. else diff_v[i] = -1;
  143. }
  144. }
  145. for(int i=0;i<diff_v.Length-1;i++)
  146. {
  147. if (diff_v[i + 1] - diff_v[i] == (isrisingedge ?2: -2))
  148. {
  149. result.Add((i + 1, first[i + 1]));
  150. }
  151. }
  152. return result;
  153. }
  154. static Dictionary<RuntimeTypeHandle, Control> ViewCache = new Dictionary<RuntimeTypeHandle, Control>();
  155. public static T CreateView<T>(bool cache = true)where T:Control
  156. {
  157. if(cache)
  158. {
  159. Type t = typeof(T);
  160. if (ViewCache.TryGetValue(t.TypeHandle, out var control)) return (T)control;
  161. else
  162. {
  163. ViewCache[t.TypeHandle] = Activator.CreateInstance<T>();
  164. return (T)ViewCache[t.TypeHandle];
  165. }
  166. }
  167. else
  168. {
  169. return Activator.CreateInstance<T>();
  170. }
  171. }
  172. public static Control CreateView(Type type, bool cache = true)
  173. {
  174. if (cache)
  175. {
  176. if (ViewCache.TryGetValue(type.TypeHandle, out var control)) return control;
  177. else
  178. {
  179. ViewCache[type.TypeHandle] = (Control)Activator.CreateInstance(type)!;
  180. return ViewCache[type.TypeHandle];
  181. }
  182. }
  183. else
  184. {
  185. return (Control)Activator.CreateInstance(type)!;
  186. }
  187. }
  188. }
  189. }