分析wav并绘制图表

我正在尝试从wav文件中打印出一个wave,但我对于我应该为样本采取的长度感到很遗憾。

这就是我喜欢的(没有颜色): 音乐wav

因此,为了读取我的数据,我使用以下代码:

// 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(); if (info.NumChannnels == 2) rightChannel = new List(); 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; } } 

BytesToFloat =将2个字节转换为介于-1和1之间的浮点数

所以现在我有2个数据列表,但现在我应该如何创建1行数?

最让我困惑的是:当你播放一首歌时,你可以在大多数音乐播放器中看到以下数据,这在我眼中是1个样本的代表。 在此处输入图像描述

但是你怎么知道每个条的值,以及样本中有多少条

您的问题是关于两种不同的音频可视化。 要绘制波形,您发布的代码即将准备好绘制,但是您将每个样本的一个条目添加到列表中。 由于音频通常是每秒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(); 

第二种可视化有时被称为谱图或频谱分析仪。 它不代表1个样本,而是表示样本块中存在的频率。 要获得此信息,您需要通过快速傅里叶变换(FFT)传递样本。 通常你会通过1024个样本的块(它应该是2的幂)。 不幸的是,如果您不熟悉DSP,FFT可能很难处理,因为您需要学习如何做以下几件事:

  • 应用窗口函数
  • 将您的音频转换为正确的输入格式(许多FFT期望输入为复数)
  • 找出哪个bin编号对应哪个频率,
  • 找到每个bin的大小并将其转换为分贝标度。

您应该能够在StackOverflow上找到有关这些主题的更多信息。 我在本文中写了一些关于如何在C#中使用FFT的文章 。