最新一直在搞声纹这一块 总结波形图这一块
首先要说的是 NAudio读写声纹的一个框架
其次ScottPlot 绘制图形非常不错
废话不多说直接上代码
xaml代码
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="1" HorizontalContentAlignment="Left" Height="26" Margin="0" Click="btnPlay_Click">选择</Button>
<Button Grid.Row="2" Width="40" Height="30" BorderThickness="0" Margin="5" DockPanel.Dock="Left" Background="Transparent" Content="播放" >
</Button>
<WpfPlot x:Name="WpfPlot1" Grid.Row="1" Grid.ColumnSpan="2" Background="Transparent"/>
</Grid>
后台代码
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = false;
dialog.Filters.Add(new CommonFileDialogFilter("WAV Files", "*.wav"));
if (dialog.ShowDialog() != CommonFileDialogResult.Ok)
return;
AnalyticalLine(dialog.FileName);
}
private void AnalyticalLine(string file)
{
WpfPlot1.Plot.Clear();
if (!System.IO.File.Exists(file))
return;
var _audiofile = new AudioFileReader(file);
byte[] datas = new byte[_audiofile.Length];
_audiofile.Read(datas, 0, datas.Length);
float[] wavdata = new float[datas.Length / sizeof(float)];
Buffer.BlockCopy(datas, 0, wavdata, 0, datas.Length);
SampleAggregator Sample = new SampleAggregator();
for (int i = 0; i < wavdata.Length; i++)
{
Sample.Add(wavdata[i], i == (wavdata.Length - 1));
}
var maxy = Sample.DataSource.Select(o => o.maxy).ToArray();
var miny = Sample.DataSource.Select(o => o.miny).ToArray();
var xs = Sample.DataSource.Select(o => o.x).ToArray();
WpfPlot1.Plot.AddFill(xs, maxy, miny, Color.Red);
WpfPlot1.Plot.AxisAuto();
WpfPlot1.Refresh();
}
public class SampleAggregator
{
public int NotificationCount;
public Action Clear;
private float maxValue;
private float minValue;
public List<DataPoint> DataSource;
private List<float> datas;
private int abscissa = 0;
private double abscissaspeed = 0;
public SampleAggregator()
{
DataSource = new List<DataPoint>();
DataSource.Add(new DataPoint(0, 0, 0));
datas = new List<float>();
//总体按照毫秒计算
abscissaspeed = (double)1 / 10
//这边是采样率16000单通道数据 这边按照每秒10个点位计算
NotificationCount = 16000 / 10;
}
public void Add(float value, bool isend)
{
datas.Add(value);
if (isend || (datas.Count + 1 > NotificationCount))
{
abscissa++;
minValue = datas.Min();
maxValue = datas.Max();
DataSource.Add(new DataPoint(abscissa * abscissaspeed, maxValue, minValue));
datas.Clear();
if (isend)
DataSource.Add(new DataPoint((abscissa + 1) * abscissaspeed, 0, 0));
}
}
}
public class DataPoint
{
public DataPoint(double x, float maxy, float miny)
{
this.x = x;
this.maxy = maxy;
this.miny = miny;
}
public double x { get; set; }
public double maxy { get; set; }
public double miny { get; set; }
}