我正在尝试从wav文件中打印出一个wave,但是我对于我应该为样本采用的长度感到很遗憾.
这就是我喜欢的(没有颜色):

因此,为了读取我的数据,我使用以下代码:
// first we need to read our wav file, so we can get our info:
byte[] wav = File.ReadAllBytes(filename);
// then we are going to get our file's info
info.NumChannnels = wav[22];
info.SampleRate = bytesToInt(wav[24], wav[25]);
// nr of samples is the length - the 44 bytes that where needed for the offset
int samples = (wav.Length - 44) / 2;
// if there are 2 channels, we need to devide the nr of sample in 2
if (info.NumChannnels == 2) samples /= 2;
// create the array
leftChannel = new List<float>();
if (info.NumChannnels == 2) rightChannel = new List<float>();
else rightChannel = null;
int pos = 44; // start of data chunk
for (int i = 0; i < samples; i++) {
leftChannel.Add(bytesToFloat(wav[pos], wav[pos + 1]));
pos += 2;
if (info.NumChannnels == 2) {
rightChannel.Add(bytesToFloat(wav[pos], wav[pos + 1]));
pos += 2;
}
}
Run Code Online (Sandbox Code Playgroud)
BytesToFloat =将2个字节转换为介于-1和1之间的浮点数
所以现在我有2个数据列表,但现在我应该如何创建1行数?
最让我困惑的是:当你播放一首歌时,你可以在大多数音乐播放器中看到以下数据,这在我看来是1个样本的代表.

但是你怎么知道每个条的值,以及样本中有多少条
Mar*_*ath 11
您的问题是关于音频的两种不同的可视化.要绘制波形,您发布的代码即将准备好绘制,但您要为每个样本添加一个条目到列表中.由于音频通常是每秒44100个样本,因此3分钟歌曲的波形将需要近800万像素.所以你要做的就是批量处理它们.对于每个说4410像素(即100ms),找到具有最高和最低值的那个,然后使用它来绘制线.实际上,通常只需找到最大Abs值并绘制对称波形即可.
下面是一些在WPF中绘制音频文件的基本WaveForm的代码,使用NAudio可以更方便地访问样本值(它可以执行WAV或MP3文件).我没有包括任何拆分左右声道,但这应该相当容易添加:
var window = new Window();
var canvas = new Canvas();
using(var reader = new AudioFileReader(file))
{
var samples = reader.Length / (reader.WaveFormat.Channels * reader.WaveFormat.BitsPerSample / 8);
var f = 0.0f;
var max = 0.0f;
// waveform will be a maximum of 4000 pixels wide:
var batch = (int)Math.Max(40, samples / 4000);
var mid = 100;
var yScale = 100;
float[] buffer = new float[batch];
int read;
var xPos = 0;
while((read = reader.Read(buffer,0,batch)) == batch)
{
for(int n = 0; n < read; n++)
{
max = Math.Max(Math.Abs(buffer[n]), max);
}
var line = new Line();
line.X1 = xPos;
line.X2 = xPos;
line.Y1 = mid + (max * yScale);
line.Y2 = mid - (max * yScale);
line.StrokeThickness = 1;
line.Stroke = Brushes.DarkGray;
canvas.Children.Add(line);
max = 0;
xPos++;
}
canvas.Width = xPos;
canvas.Height = mid * 2;
}
window.Height = 260;
var scrollViewer = new ScrollViewer();
scrollViewer.Content = canvas;
scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
window.Content = scrollViewer;
window.ShowDialog();
Run Code Online (Sandbox Code Playgroud)
第二种可视化有时被称为谱图或频谱分析仪.它不代表1个样本,而是表示样本块中存在的频率.要获得此信息,您需要通过快速傅里叶变换(FFT)传递样本.通常你会通过1024个样本的块(它应该是2的幂).不幸的是,如果您不熟悉DSP,FFT可能很难处理,因为您需要学习如何做以下几件事:
您应该能够在StackOverflow上找到有关这些主题的更多信息.我在本文中写了一些关于如何在C#中使用FFT的文章.