ć
ćźčăŻă©ăă§ăăăăăăšă«ăăăăăăăŠăăăźăăăăă
ăăăăæŹĄăźăäœăăăšăăäșă§ăšăăăăćźèŁ
ăăŠăżăŸăă
ćéĄăŻèȘćăźéłćٰă§ăŻăăŹăçșçăăăăăăăăäžèŽăăȘăă ăăăšăăäșă§ăăăźèŸșăźææ§äžèŽćźèŁ
ăæ°ćŠçă«è§Łæ±șăăȘăăŠăŻăȘăăŸăăă
ăăȘăćä»ă ....
ăŸăăŻçŹŹäžæź”éăšăăŠć°€ăćçŽăȘćźèŁ
ă§è©ŠăăŸăă
æäœéWindowsă§ćăăăă°ăăăăćż
èŠăȘăPythonăšăäœżăă
OxyPlotăäœżăŁăŠăżăŸăăăćčžéă«ăTeratailăźèłȘćă§äœżăŁăŠăăźăOxyPlotă ăŁăăăăăăăäžéšç䌌ăăăăăăăźăăȘăăšçžćœæéæăăŁăŠăăŸăăšæăă
çźæŹĄïŒé·ăăȘăŁăăźă§ïŒ
1.ćæșć
2.éłćŁ°æłąćœąăèĄšç€șăă
3.ćźèĄç”æ
ăăăŸă§ăźæé ăźGItć
4.ăăăłă°çȘăæăă
ăăăŸă§ăźGit Branchć
5.ćż
èŠăȘæłąćœąăźé·ăăèšçźă§ćČăćșă
6.äżćăăăéłćŁ°æłąćœąăć
„ćăăæłąćœąăšäžèŽăăăă©ăăć€ćź
1.ćæșć
ăă€ăŻăæșćăăăïŒæžăćżăïŒ
1000ćçšćșŠăźUSBăă€ăŻăäœżăŁăŠăăă
OXyPlotă€ăłăčăăŒă«
Nugetă§OxyPlot.Wpfăæ€çŽąăăŠăăăă
ăă¶ă€ăäžă§èĄšç€șăăăèšćź
仄äžăćèă«ăăŠ
EvryThing(https://www.voidtools.com/) ă§ăźă€ăłăčăăŒă«ćŸæ€çŽąç”æ
äœżăæčăŻçȘăźç€Ÿă§ăèŠăŠçœźăăŠă»ăăăă€ăłăčăăŒă«æă«æłšæăăă°èȘćçă«ć
šăŠă€ăłăăăŻăčăăăïŒäžèšćç
§ïŒă
〿ăăăăč
C:\Users\USER\.nuget\packages\oxyplot.wpf.shared\2.1.2\lib\net45\OxyPlot.Wpf.Shared.dll
C:\Users\USER\.nuget\packages\oxyplot.core\2.1.2\lib\net45\OxyPlot.dll
ăăă2ă€ăăăæéă ăă©ćç
§ć
ă«æćă§èżœć ăăă°ăăăæ€çŽąă§ăŻćșăȘăă
Visual studio 2022ă«ăŠă
ăă§ăăŻăăăŻăčăć€ăăăă°ăăăăăźăăăă
ăă«ăăăïŒæžăćżăïŒ
ć°ăăăŒă«ăăăŻăčăźèĄšç€șăŻPlotViewă§ăăă
2.éłćŁ°æłąćœąăèĄšç€șăă
â»NAudioăNugetă§ă€ăłăčăăŒă«ăăŠăăăŠăă ăăă
ćäșșblogăȘăźă ăæ€èšŒăăă°ăăă»ă©é©ăă»ă©æŁçąșăȘCodeă ăšèšăăźăćăăăçéąçźăȘäșșă ăŁăăăăă
æźă©ăźCodingăŻăŻăŠăȘblogăźćźèŁ ăźăŸăŸă§ă»ăŒăłăłăă€ă«ăéăŁăŠăăŸă
ăăĄăăăăźăŸăŸă ăšErrorćșăŸăăŁăŠäœżăăăźă«ăȘăăȘăă
DataPointăźæçčă§ăšă©ăŒăćșăă
ććżè ăŹăă«ă ăšăăźæçčă§èșăăšăăă ăăăăăăŸă§WPFăäœżăŁăŠăăăźă§ăăźćŻŸćżăăăăă©ăæźă©äżźæŁăźćż èŠăçĄăăŁăăźă§ăĄăăŁăšé©ăăăŁăŠè©±ă
ăăšăŻă°ă©ăèĄšç€șăźăăŠăăŠăæć „ăăă ăă ăŁăă
DeviceNumber ă«ă€ăăŠ
waveIn = new WaveIn()
{
//Labelă«èĄšç€șăăăDeviceChannelăèšćźăăă
//0ă§ăăăăă
DeviceNumber = 0, // Default
};
ć€èŠł
â»èŠçŽ æŻă«ăłăăăăŠăă ăă
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Left">
<Button Content="Button" Margin="0,0,0,10"
Height="40" Width="70" Click="Button_Click"/>
<Button Content="Button"
Height="40" Width="70" Click="Save_Click"/>
</StackPanel>
<Label VerticalAlignment="Top"
Background="AliceBlue" Height="50" Width="700" x:Name="label1" />
<oxy:PlotView
Model="{Binding oxyModel, ElementName=root}"
Controller="{Binding Controller, ElementName=root}"
x:Name="plotView" HorizontalAlignment="Center" Margin="0,111,0,0" VerticalAlignment="Top" Height="270" Width="396"/>
</Grid>ă
æŹcode
â»CodeăŻäžèĄăă€æ€èšŒăăȘăăăłăăăăŠăă ăăă
â»errorăŻćă«æłšæăăȘăăäžă€ăă€è§Łæ¶ăăŠăăŁăŠăă ăăă
â»ćčŸă€ăăŻăłăĄăłăăăšä»ăźèšäșăăæăŁăŠăăŠăŸăă
using NAudio.Wave;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace VoiceLancherTests
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitPlot();
}
WaveIn waveIn;
public PlotController Controller { get; } = new PlotController();
private void Button_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < WaveIn.DeviceCount; i++)
{
var deviceInfo = WaveIn.GetCapabilities(i);
label1.Content = string.Format("Device {0}: {1}, {2} channels",
i, deviceInfo.ProductName, deviceInfo.Channels);
}
waveIn = new WaveIn()
{
DeviceNumber = 0, // Default
};
waveIn.DataAvailable += WaveIn_DataAvailable;
waveIn.WaveFormat = new WaveFormat(sampleRate: 16000, channels: 1);
///sampleRateăŻéłćٰèȘèçšăźæłąćœąă«ćż
èŠăȘherzæ° * 1000
waveIn.StartRecording();
}
private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
// 32bită§æć€§ć€1.0fă«ăăïŒć
èšäșăźăăïŒ
///floatćă«ăă€ă€æć€§1.0fă«ć¶éăă
for (int index = 0; index < e.BytesRecorded; index += 2)
{
short sample = (short)((e.Buffer[index + 1] << 8) | e.Buffer[index + 0]);
///'<<'ăŻć·Šă·ăăæŒçźćă§ăăïŒćăăŠèŠăïŒ
///e.BufferăŻbytećăźé
ć
///8 ăăăă·ăăăăăš2ăź8äčăæăçźăăæ°ć€ă«ăȘă
///ăȘă8ăăăă·ăăăȘăźăïŒ16bit Shiftă«ăăăæłąćœąă朰ăăïŒçްăăăïŒ
float sample32 = sample / 32768f;
///'f'ăŻfloatăèĄšă
///32bit FloatăšéąéŁïŒ
////shortćăźäžéïŒăăăăŻäžéïŒă§ćČă
////16ăăăïŒ -32,768 ïœ 32,767
/// https://pspunch.com/pd/article/bit_depth/
ProcessSample(sample32);
}
}
List<float> _recorded = new List<float>(); // éłćٰăăŒăż
private LineSeries _lineSeries = new LineSeries();
// OxyPlotăźăăăźăąăă«ăšăłăłăăăŒă©ăŒ
public PlotModel oxyModel { get; } = new PlotModel();
// 軞ăźèšćź
public OxyPlot.Axes.LinearAxis AxisX { get; } = new OxyPlot.Axes.LinearAxis();
public OxyPlot.Axes.LinearAxis AxisY { get; } = new OxyPlot.Axes.LinearAxis();
private void ProcessSample(float sample)
{
_recorded.Add(sample);
if (_recorded.Count == 1024)
{
var points = _recorded.Select((v, index) =>
new DataPoint((double)index, v)
).ToList();
_lineSeries.Points.Clear();
_lineSeries.Points.AddRange(points);
plotView.InvalidatePlot(true);
_recorded.Clear();
}
}
void InitPlot()
{
var model = new PlotModel();
model.Axes.Add(new LinearAxis { Minimum = -0.1, Maximum = 0.1, Position = AxisPosition.Left, });
model.Series.Add(_lineSeries);
plotView.Model = model;
}
private void Save_Click(object sender, RoutedEventArgs e)
{
waveIn.StopRecording();
///Save recoded Data to CSV
}
}
}
ăȘă8ăăăă·ăă〿ăăăźăă«ă€ăăŠăźChatGPTă«ăăè§ŁèȘŹ
ćźćšăăăăă„ăĄăłăăŻćăăæŹĄçŹŹèšèŒăăŸăă
ăă€ăé ćă§ć俥ăăéłćٰăăŒăżă16ăăăăźă·ă§ăŒăćă«ć€æăăăăă«ćż èŠă§ăăć·Šă·ăăæŒçźăŻăăă€ăćăźäžäœăăăăă·ă§ăŒăćăźäžäœăăăă«ç§»ćăăăăăšă«ăăŁăŠă8ăăăăă16ăăăăžăźć€æăćźçŸăăŸăăăăăŠăăăźćŸăshortćăźă”ăłăă«ă-32768ăă32767ăźçŻćČăźæ”źćć°æ°çčæ°ă«æŁèŠćăăăăă«ă32768ă§ćČăćŠçăèĄăăăŠăăŸăăăăă«ăăăć „ćéłćٰă-32768ăă32767ăźçŻćČă§èĄšăăăă·ă§ăŒăćăăŒăżă§ăăŁăć Žćă§ăăæŁèŠćăăăćșćă-1.0ăă1.0ăźçŻćČă§èĄšăăăăăă«ăȘăăŸăă
3.ćźèĄç”æ
æć€ăšCodingăźéŁćșŠăŻäœăă
ChartèĄšç€șăŸă§ăźăăŠăăŠăćăăăȘăăšèŠćŽăăăšæăă
chartăèĄšç€șăăăȘăć Žć
OxyPlotăăȘăă
ăă€ăŻăæŁćžžă«æ„ç¶ăăăŠăȘăă
ăă€ăŻăä»ăźăąăăȘă±ăŒă·ă§ăłă«ăăŁăŠæä»ć¶ćŸĄăăăŠăă
PlotViewăźćæćăćșæ„ăŠăăȘă
çŸăă„ăŒăăŒăźćç»ăèŠłăŠăăȘă
ăăźèŸșăăäžă€äžă€ăă§ăăŻăăŸăăăă
æłąćœąăăŒăżăăĄăăăšæ„ăŠăăăçąșèȘăăă
ăăŹăŒăŻăă€ăłăăæŽ»çšăăŸăăăă
ăăźèĄăźæçčă§ăŻpointsăŻnullăźăŸăŸă§ăă
ăăăŸă§ăźæé ăźGItć
ăăăžă§ăŻăăăĄă€ă«ă§ăăăVisual Studio2022 .net7ăäœżăŁăŠăăŸăă
ä»ćŸăăȘăăčăææ°ăźç°ćąăäœżăăŸăăć€ăăȘăŁăăăȘăŻăšăčăæŹĄçŹŹă§æŽæ°ăăŠăăăŸăă
git Clone https://github.com/Sheephuman/VoiceLancherTests.git
URLă ăă§è©Šăăăă©ăăŁă±ă.gitćż èŠă ăŁăä»¶ă
ăăźćŸăźæé ăBranchăăŠćăăăȘă©ăźæœçă詊ăżăăăšæăă
4.ăăăłă°çȘăæăă
ăăăłă°çȘïŒăȘă«ăăçŸćłăăăźïŒ çăȘæăă§äžèŠă ăăăšæăŁăŠèŠăăȘăăŁăăă§ăăăèȘżăčăăéłćŁ°è§Łæăćźčæă«ăăăăźăăăăçźæă仿§ă«ćăăŠćż èŠăȘćźèŁ ă ăăăšăăäșă§ăăăèżœć ăăŸăă
è©łçŽ°ăȘèȘŹæ
ć Žćă«ăăŁăŠăŻäžĄç«ŻăźèŠçŽ ăăŒăă«ăȘăăšăăăăăłă°çȘăäœżăăčăăăç„ăăȘăă
Math.NET NumericsăNugetă§ă€ăłăčăăŒă«ăăŸăă
HamingçȘèĄšç€șçšăźChartăć„ă«çšæăăŸăă
ćæćçšăźInitPlotăćŒæ°ăćăăăźă«æčé ăăŸăă
void InitPlot(LineSeries _lineSeries, PlotView _plotView )
{
var model = new PlotModel();
///ć
éšăłăłăăăŒă«ć€ćź
if (_plotView.Name == hammingPlotView.Name)
{
model.Axes.Clear();
model.Axes.Add(new LinearAxis { Minimum = 0, Maximum = 10000, Position = AxisPosition.Bottom });
model.Axes.Add(new LinearAxis { Minimum = 0, Maximum = 4, Position = AxisPosition.Left, });
}
model.Series.Add(_lineSeries);
_plotView.Model = model;
}
////ăłăłăčăă©ăŻăż
public MainWindow()
{
InitializeComponent();
InitPlot(_lineSeries,plotView);
InitPlot(_hammingLineSeries, hammingPlotView);
}
HammingçȘçšăźSeriesïŒçł»ćïŒăšăąăă«ăçšæăăŸăă
////Field for Haming Window
private LineSeries _hammingLineSeries = new LineSeries();
public PlotModel hammingOxyModel { get; } = new PlotModel();
HammingçȘçšăźăĄăœăăăäœæăăŸă
èłȘćăăăŸă§ăăȘăăăȘăç°Ąćă ăŁăă
ăłăĄăłăă«ăăăšWindowSizeăšăŻæłąćœąăăŒăżfloat<List>ăźă«ăŠăłăïŒèŠçŽ æ°ïŒăæăăăă
List<DataPoint> HammingMethod()
{
var window = MathNet.Numerics.Window.Hamming(_recorded.Count);
ăăă ///ăăźăŸăŸă ăšWinFormăšăźææ§ćç
§ăè”·ăăïŒăăă©ăïŒ
ă
var haming_recorded = _recorded.Select((v, i) => v * (float)window[i]).ToList();
Complex[] complexData = haming_recorded.Select(v => new Complex(v, 0.0)).ToArray();
///è€çŽ æ°é
ćăăŒăżă«ć€æ
Fourier.Forward(complexData, FourierOptions.Matlab); // arbitrary length
/// ăăŒăȘăšć€æăăćŠçăèżă
var s = haming_recorded.Count * (1.0 / 16000.0);
///èŠçŽ æ°ă«ïŒ1 / Hertzæ°ïŒăæăăïŒăăźć ŽćăŻ16kHzïŒ
///ăăăăăȘăăšDataPointă«ćż
èŠăȘè§ŁććșŠăćŸăăăăæłąćœąă朰ăă
var point = complexData.Take(complexData.Count() / 2).Select((v, index) =>
new DataPoint((double)index / s,
Math.Sqrt(v.Real * v.Real + v.Imaginary * v.Imaginary))
).ToList();
////æłąćœąăăŒăżăźćčłæčæ čăèšçź
////Enumerable.Take ăĄăœăă (System.Linq)
ă ////ă·ăŒă±ăłăčăźć
é ăăèŠçŽ ăèżă
this.hammingPlotView.InvalidatePlot(true); return point;
}
ăăăProcessSampleăĄăœăăć ă§ćźèĄăăŸăă
private void ProcessSample(float sample)
{
_recorded.Add(sample);
if (_recorded.Count == 1024)
ă {////çç„}
_lineSeries.Points.Clear();
_hammingLineSeries.Points.Clear();
_lineSeries.Points.AddRange(points);
_hammingLineSeries.Points.AddRange(HammingMethod());
plotView.InvalidatePlot(true);
hammingPlotView.InvalidatePlot(true);
_recorded.Clear();
}
}
ăăăŸă§ăźćźèĄç”æ
ăăăŸă§ăźGit Branchć
仄ćăźCodeăŻ
git clone https://github.com/Sheephuman/VoiceLancherTests.git
ă§ăăźăŸăŸććŸă§ăăŸăă
git clone -b HammingWindow_Branch https://github.com/Sheephuman/VoiceLancherTests.git
5.ćż èŠăȘæłąćœąăźé·ăăèšçźă§ćČăćșă
ăăăŻćăȘăèšçźăźćéĄă§ăć€ć性ćŠć „ăăäșșçšćșŠăȘăăăèšçźćșæ„ăăšæăăă ăă©ăŸăăšăăăăèȘżăčăŠćČăćșăăă«ăăæăăăȘăăŠăăă
ăŸăćźéă«éČéłă«ćż èŠăȘç§æ°ăšéłćٰèȘèă«é©ăăă”ăłăă«ăŹăŒăăăăćż èŠăȘăăŒăżăźé·ăăćČăćșăăéČéłă«äœżçšăăăăŒăżăŻăčăăăăŠă©ăăă§èšæžŹăăăšăă2ç§ïœ5ç§ăšăăŁăăšăăïŒćŻŸè±ĄăźăąăăȘă±ăŒă·ă§ăłćăăăźäžéšăćŒăčă°ăăïŒ
éłćٰèȘèă«é©ăăă”ăłăă«ăŹăŒăăŻ16khză§ććăšăźăăšă
â»ćŸæ„ăăçČŸćșŠăäžăăçșă«32khză«ć€ăăăăăŠăŸăă
ă16(khz) * 1000 * 5(ç§) = 80000ïŒplotæ°ïŒ
ăăźæ°ă«ćŻŸăăŠ2ăźăčăäčă«æăèżăèȘç¶æ°ăćČăćșăïŒé«éăăŒăȘăšć€æ-FFTăŻ2ăźăčăäčă§ăȘăăšćșæ„ăȘăăšăăć¶éăăăă-ćèïŒhttps://cognicull.com/ja/f5q2jl62
ăChatGPTăźWebçăżăăăȘćșć
žäžæăźèŹă”ă€ăăïŒ
éąæ°é»ćă«ăæ ŁăăăăŁăăäœżăæčăăăćăăăȘăăŁăă
é©ćœă«C#ă«ć€æăăŠ
private void Calc_Click(object sender, RoutedEventArgs e)
{
int n = 80000;
string bin = Convert.ToString(n, 2);
int len = bin.Length;
Debug.WriteLine(len - 1);
}
ç”æ : 16
仄äžăă2ăź16äčăȘăă17äčăäœżçšăăă°ăăăăšă«ăȘăă
ćŸăăăæ°ăŻ65536ïŒ5ç§æȘæșïŒă§ăăă
ăăă»ă©ăźèŠçŽ æ°ăšăȘăăšăăȘăchartèĄšç€șăéăăȘăŁăŠăăŸăăăéăăšăăăăćČăćșăăæłąćœąăźé·ăă§ăă4ç§~5ç§ćŒ±æŻă«ăȘăŁăŠăăăăăéłćٰèȘèă©ăłăăŁăŒăäœăăźăçźçăȘăźă§ćéĄăȘăă ăăă
CSVć
ç”æ§äŸżć©ăȘèšäșăăăŁăăă§èŒăăšăăéćæăĄăœăăăšăIDisposableăŸă§ćźèŁ ăăŠăăăźăçšæăăăă
6.äżćăăăéłćŁ°æłąćœąăć „ćăăæłąćœąăšäžèŽăăăă©ăăć€ćź
æșăæăăŠăźæŽæ°ăéèŻä»äșăšäœèȘżäžèŻă§ăȘăăȘăäœæ„ćșæ„ăȘăăŁăă
ćé ă«ăæžăăăă©äžèŽăŻïŒć€ćïŒ100ïŒ
ăăŸăăăäžèŽçăæ°ć€ăšăăŠćșăăăźăèŠă€ăăăźă§ăăă詊ăăŠăżăăăšăăé
ă§ăă
wildpieăźæ„èš(https://wildpie.hatenablog.com/entry/2014/10/13/122909 )ă«ăăăŸăăăæèŹăăăȘăă§ăăăć€ćăăăăăăăăȘăăźă§ă
ćźèĄç”æăźèšéČèšäș
èšäșć ă§èŠçŽ æ°ăç”ă蟌ăćŻŸçăæœăăŸăăïŒćźăăăă°ăčăăăŻăăŠăă ăăïŒă
äžćżæćăăŠăŸăăźă§ăăăă§æŹĄćăŻæćźăźăąăăȘă±ăŒă·ă§ăłăè”·ćăăăăšăăŸă§ăŻèĄăăŸăăăăźăŸăŸă ăšăă€ășçăźćœ±éżă§MinDistanceç”æăćźćźăăȘăăăăȘăźă§ăæŹĄćæŽæ°ă§ăŻăăŒăăčăăŁă«ăżăźćźèŁ ă詊ăżăäșćźă§ăïŒăăăăšăćąăăȘăć ŽćăŻblogçă«è»ąèŒăăăŠé ăăŸă(çŹ)ïŒă
Gir Branchć
ćźăŻăȘăăžăăȘă仄ćăźăŸăŸæŽæ°ăăăŠăȘăăŁăăźă§ïŒćœç¶äœæ„ć ćźčăŻçĄă«ćž°ăăïŒăé©ćăȘæäœæčæłăèŠăăăăă§ComităçŽăăŸăăăéłèŹă
git clone -b BPMatching_Brunch https://github.com/Sheephuman/VoiceLancherTests.git
testæžăżă§ăă
ăăă§ăŻCSVäżćăŻăŸă èĄăăăăăŒăă«çąșäżăăăListăźé
ćăšăăźăŸăŸæŻèŒăăŠăăŸăă
ćéĄçčăŻèšçźă«æéăæăăéăăïŒRyzen7 3700xă§35ç§ăăăïŒäșă§ăæčćă詊ăżăŠăăăšăăă§ăă
â6ç§ććŸăŸă§ççžźă
ăłăĄăłăæèżă
Pythonă§èĄăæčæłăŻăăăăćąăăă詊ăăŸăă
æłąćœąă«ăăŁă«ăżăæăă
ćșćç”æăćźćźăăȘăăźă§ăăŒăăčăăŁă«ăżăæăăŸăă
æłąćœąăäżćăăŠăăŒăżăăŒăčćăă
ăŸă ăăăšăăŁăææź”ăăąă€ăăŁăąăŻăȘăăă§ăăăăăĄă€ă«ă”ă€ășăăăȘăè„性ćăăäșăäșæłăăăŸăă
ăăă«ćŻŸăăæœçăšăăŠăăăŒăżăăŒăčç»éČæă«idăȘă©ăä»ć ăăŠăăźăŸăŸLinkăăæčćŒăćăäșă«ăăŸăăăăă«ăăăăŒăżăăŒăčăźć
šæłąćœąăç
§ćăȘă©ăšăăäșăŻéżăăăăŸăă










Comments
Let's comment your feelings that are more than good