diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/DataService/IApplicationDataService.cs b/Correlator/DataService/IApplicationDataService.cs index fd9fb5a..0dc0b5a 100644 --- a/Correlator/DataService/IApplicationDataService.cs +++ b/Correlator/DataService/IApplicationDataService.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Windows.Media; using Correlator.Model; namespace Correlator.DataService @@ -22,5 +23,11 @@ /// /// int GetSoundVelocity(string material, int pipeDiameter); + + /// + /// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值) + /// + /// 所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变) + Color[] GetAllHsvColors(); } } \ No newline at end of file diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/DataService/IApplicationDataService.cs b/Correlator/DataService/IApplicationDataService.cs index fd9fb5a..0dc0b5a 100644 --- a/Correlator/DataService/IApplicationDataService.cs +++ b/Correlator/DataService/IApplicationDataService.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Windows.Media; using Correlator.Model; namespace Correlator.DataService @@ -22,5 +23,11 @@ /// /// int GetSoundVelocity(string material, int pipeDiameter); + + /// + /// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值) + /// + /// 所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变) + Color[] GetAllHsvColors(); } } \ No newline at end of file diff --git a/Correlator/Events/AudioSampleEvent.cs b/Correlator/Events/AudioSampleEvent.cs deleted file mode 100644 index 2309da1..0000000 --- a/Correlator/Events/AudioSampleEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Prism.Events; - -namespace Correlator.Events -{ - public class AudioSampleEvent : PubSubEvent - { - - } -} \ No newline at end of file diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/DataService/IApplicationDataService.cs b/Correlator/DataService/IApplicationDataService.cs index fd9fb5a..0dc0b5a 100644 --- a/Correlator/DataService/IApplicationDataService.cs +++ b/Correlator/DataService/IApplicationDataService.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Windows.Media; using Correlator.Model; namespace Correlator.DataService @@ -22,5 +23,11 @@ /// /// int GetSoundVelocity(string material, int pipeDiameter); + + /// + /// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值) + /// + /// 所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变) + Color[] GetAllHsvColors(); } } \ No newline at end of file diff --git a/Correlator/Events/AudioSampleEvent.cs b/Correlator/Events/AudioSampleEvent.cs deleted file mode 100644 index 2309da1..0000000 --- a/Correlator/Events/AudioSampleEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Prism.Events; - -namespace Correlator.Events -{ - public class AudioSampleEvent : PubSubEvent - { - - } -} \ No newline at end of file diff --git a/Correlator/Util/AudioVisualizer.cs b/Correlator/Util/AudioVisualizer.cs new file mode 100644 index 0000000..c4b1f45 --- /dev/null +++ b/Correlator/Util/AudioVisualizer.cs @@ -0,0 +1,187 @@ +using System; +using System.Linq; +using FftSharp; +using FftSharp.Windows; + +namespace Correlator.Util +{ + public class AudioVisualizer + { + /// + /// 采样数据 + /// + public double[] SampleData { get; } + + /// + /// + /// + /// 控制频谱数量,数量越多,界面显示波动的频谱越多,建议256就好 + /// + public AudioVisualizer(int waveDataSize) + { + if (!Get2Flag(waveDataSize)) + { + throw new ArgumentException("长度必须是 2 的 n 次幂"); + } + + SampleData = new double[waveDataSize]; + } + + /// + /// 判断是否是 2 的整数次幂 + /// + /// + /// + private bool Get2Flag(int num) + { + if (num < 1) + { + return false; + } + + return (num & num - 1) == 0; + } + + public void PushSampleData(double[] waveData) + { + if (waveData.Length > SampleData.Length) + { + Array.Copy(waveData, waveData.Length - SampleData.Length, SampleData, 0, SampleData.Length); + } + else + { + Array.Copy(SampleData, waveData.Length, SampleData, 0, SampleData.Length - waveData.Length); + Array.Copy(waveData, 0, SampleData, SampleData.Length - waveData.Length, waveData.Length); + } + } + + /// + /// 获取频谱数据 (数据已经删去共轭部分) + /// + /// + public double[] GetSpectrumData() + { + var len = SampleData.Length; + var data = new Complex[len]; + + for (var i = 0; i < len; i++) + { + data[i] = new Complex(SampleData[i], 0); + } + + Transform.FFT(data); + + var halfLen = len / 2; + var result = new double[halfLen]; // 傅里叶变换结果左右对称, 只需要取一半 + for (var i = 0; i < halfLen; i++) + { + result[i] = data[i].Magnitude / len; + } + + var window = new Bartlett(); + window.Create(halfLen); + window.ApplyInPlace(result); + + return result; + } + + /// + /// 简单的数据模糊 + /// + /// 数据 + /// 模糊半径 + /// 结果 + public static double[] MakeSmooth(double[] data, int radius) + { + var weights = GetWeights(radius); + var buffer = new double[1 + radius * 2]; + + var result = new double[data.Length]; + if (data.Length < radius) + { + data.Average(); + result.SetValue(data, 0); + return result; + } + + for (var i = 0; i < radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = radius; i < data.Length - radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[j] = data[i - j]; + } + + buffer[radius] = data[i]; + + for (var j = 0; j < radius; j++) // + { + buffer[radius + j + 1] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = data.Length - radius; i < data.Length; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i - j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + return result; + } + + private static double[] GetWeights(int radius) + { + double Gaussian(double x) => Math.Pow(Math.E, -4 * x * x); // 高斯函数 + + var len = 1 + radius * 2; // 长度 + var end = len - 1; // 最后的索引 + var radiusF = (double)radius; // 半径浮点数 + var weights = new double[len]; // 权重 + + for (var i = 0; i <= radius; i++) // 先把右边的权重算出来 + { + weights[radius + i] = Gaussian(i / radiusF); + } + + for (var i = 0; i < radius; i++) // 把右边的权重拷贝到左边 + { + weights[i] = weights[end - i]; + } + + var total = weights.Sum(); + for (var i = 0; i < len; i++) // 使权重合为 0 + { + weights[i] /= total; + } + + return weights; + } + + private static void ApplyWeights(double[] buffer, double[] weights) + { + var len = buffer.Length; + for (var i = 0; i < len; i++) + { + buffer[i] *= weights[i]; + } + } + } +} \ No newline at end of file diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/DataService/IApplicationDataService.cs b/Correlator/DataService/IApplicationDataService.cs index fd9fb5a..0dc0b5a 100644 --- a/Correlator/DataService/IApplicationDataService.cs +++ b/Correlator/DataService/IApplicationDataService.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Windows.Media; using Correlator.Model; namespace Correlator.DataService @@ -22,5 +23,11 @@ /// /// int GetSoundVelocity(string material, int pipeDiameter); + + /// + /// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值) + /// + /// 所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变) + Color[] GetAllHsvColors(); } } \ No newline at end of file diff --git a/Correlator/Events/AudioSampleEvent.cs b/Correlator/Events/AudioSampleEvent.cs deleted file mode 100644 index 2309da1..0000000 --- a/Correlator/Events/AudioSampleEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Prism.Events; - -namespace Correlator.Events -{ - public class AudioSampleEvent : PubSubEvent - { - - } -} \ No newline at end of file diff --git a/Correlator/Util/AudioVisualizer.cs b/Correlator/Util/AudioVisualizer.cs new file mode 100644 index 0000000..c4b1f45 --- /dev/null +++ b/Correlator/Util/AudioVisualizer.cs @@ -0,0 +1,187 @@ +using System; +using System.Linq; +using FftSharp; +using FftSharp.Windows; + +namespace Correlator.Util +{ + public class AudioVisualizer + { + /// + /// 采样数据 + /// + public double[] SampleData { get; } + + /// + /// + /// + /// 控制频谱数量,数量越多,界面显示波动的频谱越多,建议256就好 + /// + public AudioVisualizer(int waveDataSize) + { + if (!Get2Flag(waveDataSize)) + { + throw new ArgumentException("长度必须是 2 的 n 次幂"); + } + + SampleData = new double[waveDataSize]; + } + + /// + /// 判断是否是 2 的整数次幂 + /// + /// + /// + private bool Get2Flag(int num) + { + if (num < 1) + { + return false; + } + + return (num & num - 1) == 0; + } + + public void PushSampleData(double[] waveData) + { + if (waveData.Length > SampleData.Length) + { + Array.Copy(waveData, waveData.Length - SampleData.Length, SampleData, 0, SampleData.Length); + } + else + { + Array.Copy(SampleData, waveData.Length, SampleData, 0, SampleData.Length - waveData.Length); + Array.Copy(waveData, 0, SampleData, SampleData.Length - waveData.Length, waveData.Length); + } + } + + /// + /// 获取频谱数据 (数据已经删去共轭部分) + /// + /// + public double[] GetSpectrumData() + { + var len = SampleData.Length; + var data = new Complex[len]; + + for (var i = 0; i < len; i++) + { + data[i] = new Complex(SampleData[i], 0); + } + + Transform.FFT(data); + + var halfLen = len / 2; + var result = new double[halfLen]; // 傅里叶变换结果左右对称, 只需要取一半 + for (var i = 0; i < halfLen; i++) + { + result[i] = data[i].Magnitude / len; + } + + var window = new Bartlett(); + window.Create(halfLen); + window.ApplyInPlace(result); + + return result; + } + + /// + /// 简单的数据模糊 + /// + /// 数据 + /// 模糊半径 + /// 结果 + public static double[] MakeSmooth(double[] data, int radius) + { + var weights = GetWeights(radius); + var buffer = new double[1 + radius * 2]; + + var result = new double[data.Length]; + if (data.Length < radius) + { + data.Average(); + result.SetValue(data, 0); + return result; + } + + for (var i = 0; i < radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = radius; i < data.Length - radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[j] = data[i - j]; + } + + buffer[radius] = data[i]; + + for (var j = 0; j < radius; j++) // + { + buffer[radius + j + 1] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = data.Length - radius; i < data.Length; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i - j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + return result; + } + + private static double[] GetWeights(int radius) + { + double Gaussian(double x) => Math.Pow(Math.E, -4 * x * x); // 高斯函数 + + var len = 1 + radius * 2; // 长度 + var end = len - 1; // 最后的索引 + var radiusF = (double)radius; // 半径浮点数 + var weights = new double[len]; // 权重 + + for (var i = 0; i <= radius; i++) // 先把右边的权重算出来 + { + weights[radius + i] = Gaussian(i / radiusF); + } + + for (var i = 0; i < radius; i++) // 把右边的权重拷贝到左边 + { + weights[i] = weights[end - i]; + } + + var total = weights.Sum(); + for (var i = 0; i < len; i++) // 使权重合为 0 + { + weights[i] /= total; + } + + return weights; + } + + private static void ApplyWeights(double[] buffer, double[] weights) + { + var len = buffer.Length; + for (var i = 0; i < len; i++) + { + buffer[i] *= weights[i]; + } + } + } +} \ No newline at end of file diff --git a/Correlator/ViewModels/AudioFileViewModel.cs b/Correlator/ViewModels/AudioFileViewModel.cs index a9579a8..8366c70 100644 --- a/Correlator/ViewModels/AudioFileViewModel.cs +++ b/Correlator/ViewModels/AudioFileViewModel.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Windows.Controls; using System.Windows.Threading; -using Correlator.Events; using Correlator.Model; using Correlator.Util; using HandyControl.Controls; @@ -134,13 +133,6 @@ } CurrentValue = _audioFileReader.CurrentTime.Seconds; - - var buffer = new float[1000]; - var samplesRead = _audioFileReader.Read(buffer, 0, buffer.Length); - var samples = buffer.Take(samplesRead).Select(x => (double)Math.Abs(x)); - var array = samples.ToArray(); - - eventAggregator.GetEvent().Publish(array); }; GoBackCommand = new DelegateCommand(delegate diff --git a/Correlator/App.config b/Correlator/App.config index a673178..30cf21c 100644 --- a/Correlator/App.config +++ b/Correlator/App.config @@ -133,6 +133,14 @@ + + + + + + + + \ No newline at end of file diff --git a/Correlator/Correlator.csproj b/Correlator/Correlator.csproj index 1dc857e..f593d28 100644 --- a/Correlator/Correlator.csproj +++ b/Correlator/Correlator.csproj @@ -65,6 +65,9 @@ ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + ..\packages\FftSharp.2.1.0\lib\netstandard2.0\FftSharp.dll + ..\packages\HandyControl.3.3.0\lib\net48\HandyControl.dll @@ -144,8 +147,8 @@ ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll - - ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll @@ -155,15 +158,15 @@ ..\packages\System.Drawing.Common.4.7.2\lib\net461\System.Drawing.Common.dll - - ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll @@ -232,7 +235,6 @@ SoundSpeedDialog.xaml - @@ -261,6 +263,7 @@ + diff --git a/Correlator/DataService/ApplicationDataServiceImpl.cs b/Correlator/DataService/ApplicationDataServiceImpl.cs index 3da8760..1b830bb 100644 --- a/Correlator/DataService/ApplicationDataServiceImpl.cs +++ b/Correlator/DataService/ApplicationDataServiceImpl.cs @@ -1,6 +1,7 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Windows.Media; using Correlator.Model; using Correlator.Util; using Newtonsoft.Json; @@ -98,5 +99,42 @@ return 0; } } + + public Color[] GetAllHsvColors() + { + var result = new Color[256 * 6]; + + for (var i = 0; i <= 255; i++) + { + result[i] = Color.FromArgb(255, 255, (byte)i, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[256 + i] = Color.FromArgb(255, (byte)(255 - i), 255, 0); + } + + for (var i = 0; i <= 255; i++) + { + result[512 + i] = Color.FromArgb(255, 0, 255, (byte)i); + } + + for (var i = 0; i <= 255; i++) + { + result[768 + i] = Color.FromArgb(255, 0, (byte)(255 - i), 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1024 + i] = Color.FromArgb(255, (byte)i, 0, 255); + } + + for (var i = 0; i <= 255; i++) + { + result[1280 + i] = Color.FromArgb(255, 255, 0, (byte)(255 - i)); + } + + return result; + } } } \ No newline at end of file diff --git a/Correlator/DataService/IApplicationDataService.cs b/Correlator/DataService/IApplicationDataService.cs index fd9fb5a..0dc0b5a 100644 --- a/Correlator/DataService/IApplicationDataService.cs +++ b/Correlator/DataService/IApplicationDataService.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Windows.Media; using Correlator.Model; namespace Correlator.DataService @@ -22,5 +23,11 @@ /// /// int GetSoundVelocity(string material, int pipeDiameter); + + /// + /// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值) + /// + /// 所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变) + Color[] GetAllHsvColors(); } } \ No newline at end of file diff --git a/Correlator/Events/AudioSampleEvent.cs b/Correlator/Events/AudioSampleEvent.cs deleted file mode 100644 index 2309da1..0000000 --- a/Correlator/Events/AudioSampleEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Prism.Events; - -namespace Correlator.Events -{ - public class AudioSampleEvent : PubSubEvent - { - - } -} \ No newline at end of file diff --git a/Correlator/Util/AudioVisualizer.cs b/Correlator/Util/AudioVisualizer.cs new file mode 100644 index 0000000..c4b1f45 --- /dev/null +++ b/Correlator/Util/AudioVisualizer.cs @@ -0,0 +1,187 @@ +using System; +using System.Linq; +using FftSharp; +using FftSharp.Windows; + +namespace Correlator.Util +{ + public class AudioVisualizer + { + /// + /// 采样数据 + /// + public double[] SampleData { get; } + + /// + /// + /// + /// 控制频谱数量,数量越多,界面显示波动的频谱越多,建议256就好 + /// + public AudioVisualizer(int waveDataSize) + { + if (!Get2Flag(waveDataSize)) + { + throw new ArgumentException("长度必须是 2 的 n 次幂"); + } + + SampleData = new double[waveDataSize]; + } + + /// + /// 判断是否是 2 的整数次幂 + /// + /// + /// + private bool Get2Flag(int num) + { + if (num < 1) + { + return false; + } + + return (num & num - 1) == 0; + } + + public void PushSampleData(double[] waveData) + { + if (waveData.Length > SampleData.Length) + { + Array.Copy(waveData, waveData.Length - SampleData.Length, SampleData, 0, SampleData.Length); + } + else + { + Array.Copy(SampleData, waveData.Length, SampleData, 0, SampleData.Length - waveData.Length); + Array.Copy(waveData, 0, SampleData, SampleData.Length - waveData.Length, waveData.Length); + } + } + + /// + /// 获取频谱数据 (数据已经删去共轭部分) + /// + /// + public double[] GetSpectrumData() + { + var len = SampleData.Length; + var data = new Complex[len]; + + for (var i = 0; i < len; i++) + { + data[i] = new Complex(SampleData[i], 0); + } + + Transform.FFT(data); + + var halfLen = len / 2; + var result = new double[halfLen]; // 傅里叶变换结果左右对称, 只需要取一半 + for (var i = 0; i < halfLen; i++) + { + result[i] = data[i].Magnitude / len; + } + + var window = new Bartlett(); + window.Create(halfLen); + window.ApplyInPlace(result); + + return result; + } + + /// + /// 简单的数据模糊 + /// + /// 数据 + /// 模糊半径 + /// 结果 + public static double[] MakeSmooth(double[] data, int radius) + { + var weights = GetWeights(radius); + var buffer = new double[1 + radius * 2]; + + var result = new double[data.Length]; + if (data.Length < radius) + { + data.Average(); + result.SetValue(data, 0); + return result; + } + + for (var i = 0; i < radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = radius; i < data.Length - radius; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[j] = data[i - j]; + } + + buffer[radius] = data[i]; + + for (var j = 0; j < radius; j++) // + { + buffer[radius + j + 1] = data[i + j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + for (var i = data.Length - radius; i < data.Length; i++) + { + for (var j = 0; j < radius; j++) // + { + buffer[radius + 1 + j] = data[i - j]; + } + + ApplyWeights(buffer, weights); + result[i] = buffer.Sum(); + } + + return result; + } + + private static double[] GetWeights(int radius) + { + double Gaussian(double x) => Math.Pow(Math.E, -4 * x * x); // 高斯函数 + + var len = 1 + radius * 2; // 长度 + var end = len - 1; // 最后的索引 + var radiusF = (double)radius; // 半径浮点数 + var weights = new double[len]; // 权重 + + for (var i = 0; i <= radius; i++) // 先把右边的权重算出来 + { + weights[radius + i] = Gaussian(i / radiusF); + } + + for (var i = 0; i < radius; i++) // 把右边的权重拷贝到左边 + { + weights[i] = weights[end - i]; + } + + var total = weights.Sum(); + for (var i = 0; i < len; i++) // 使权重合为 0 + { + weights[i] /= total; + } + + return weights; + } + + private static void ApplyWeights(double[] buffer, double[] weights) + { + var len = buffer.Length; + for (var i = 0; i < len; i++) + { + buffer[i] *= weights[i]; + } + } + } +} \ No newline at end of file diff --git a/Correlator/ViewModels/AudioFileViewModel.cs b/Correlator/ViewModels/AudioFileViewModel.cs index a9579a8..8366c70 100644 --- a/Correlator/ViewModels/AudioFileViewModel.cs +++ b/Correlator/ViewModels/AudioFileViewModel.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Windows.Controls; using System.Windows.Threading; -using Correlator.Events; using Correlator.Model; using Correlator.Util; using HandyControl.Controls; @@ -134,13 +133,6 @@ } CurrentValue = _audioFileReader.CurrentTime.Seconds; - - var buffer = new float[1000]; - var samplesRead = _audioFileReader.Read(buffer, 0, buffer.Length); - var samples = buffer.Take(samplesRead).Select(x => (double)Math.Abs(x)); - var array = samples.ToArray(); - - eventAggregator.GetEvent().Publish(array); }; GoBackCommand = new DelegateCommand(delegate diff --git a/Correlator/Views/AudioFileView.xaml b/Correlator/Views/AudioFileView.xaml index ac2cfb8..cf6531e 100644 --- a/Correlator/Views/AudioFileView.xaml +++ b/Correlator/Views/AudioFileView.xaml @@ -11,6 +11,8 @@ d:DataContext="{d:DesignInstance Type=vm:AudioFileViewModel}" d:DesignHeight="1080" d:DesignWidth="1920" + Loaded="AudioFileView_OnLoaded" + Unloaded="AudioFileView_OnUnloaded" mc:Ignorable="d"> @@ -36,7 +38,7 @@ - +