1

我的任务是在 C# 中分析 wav 音频文件(过滤、FFT 等)。目前,我一直在尝试将字节正确转换为双精度,以便使用 scottplot 绘制波形的音频信号,我曾尝试使用 Naaudio 库,但在读取音频数据并绘制它时没有发现任何成功,最终破坏我的项目。下面的代码是我将 wav 字节读入数组并将其转换为双精度数组以使用不工作的 scottplot 绘制信号的地方,我正在使用 windows 窗体应用程序(.NET 核心)

        byte[] wavData = File.ReadAllBytes(@"C:\Users\me\Documents\africa-song.wav");
        double[] values = new double[wavData.Length / 8];
        Buffer.BlockCopy(wavData, 0, values, 0, values.Length * 8);
        formsPlot1.plt.PlotSignal(values, 44100);

如果有更好的库我可以使用或解决这个问题,将不胜感激

4

1 回答 1

1

使用 NAudio 从 WAV 文件中读取值

您可以直接从 WAV 文件中读取字节,但这并不总是那么容易,因为不同的 WAV 文件具有不同大小的标头,因此您并不总是知道第一个数据字节的位置。您还必须阅读和解释标头以了解数据格式是什么(每个样本的字节数,是否是浮点数等)以及有多少个通道。

从 WAV 文件中读取值的更简单方法是使用NAudio。我使用这种方法将任何 WAV 文件数据中的值转换为双精度数组:

static (double[] audio, int sampleRate) ReadWav(string filePath)
{
    using var afr = new NAudio.Wave.AudioFileReader(filePath);
    int sampleRate = afr.WaveFormat.SampleRate;
    int sampleCount = (int)(afr.Length / afr.WaveFormat.BitsPerSample / 8);
    int channelCount = afr.WaveFormat.Channels;
    var audio = new List<double>(sampleCount);
    var buffer = new float[sampleRate * channelCount];
    int samplesRead = 0;
    while ((samplesRead = afr.Read(buffer, 0, buffer.Length)) > 0)
        audio.AddRange(buffer.Take(samplesRead).Select(x => (double)x));
    return (audio.ToArray(), sampleRate);
}

用 ScottPlot 绘制值

与内置图形库不同,ScottPlot 允许鼠标交互式平移和缩放具有数百万点的数据集,因此即使您的音频文件长达一个小时,您也可以轻松地显示它。看起来您与原始代码非常接近!

(double[] audio, int sampleRate) = ReadWav("demo.wav");

formsPlot1.plt.PlotSignal(audio, sampleRate);
formsPlot1.plt.Title("WAV File Data");
formsPlot1.plt.XLabel("Time (seconds)");
formsPlot1.plt.YLabel("Audio Value");
formsPlot1.plt.AxisAuto(0);
formsPlot1.Render();

在此处输入图像描述

于 2020-12-19T17:24:05.577 回答