3

我完成了从 WAV 文件中获取行数据。所以现在,我知道了有关 WAV 文件的信息,例如 DataRate 和 SamplingPerBits 等。

而且我在读取WAV文件后有几种数据类型:16位-[]Int16,8位-[]byte。

现在我正在尝试将 []Int16 转换为 []float!

我找到了 NAudio.wave 函数 Wave16ToFloatProvider()。

我见过Converting 16 bit to 32-nit floating point。但我无法理解它,因为我不需要编写 WaveFileWriter。所以我试着不用 WaveFileWriter。这是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NAudio;
using NAudio.Wave;

namespace WaveREader
{
    class WaveReader
    {
        WaveFileReader reader = new WaveFileReader("wavetest.wav");
        IWaveProvider stream32 = new Wave16ToFloatProvider(reader);
        byte[] buffer = new byte[8192];
        float[] DATASIXTEEN;
        for (int i = 0; i < buffer.Length; i++)
        {
            DATASIXTEEN = new float[buffer.Length];
            DATASIXTEEN[i] = stream32.Read(buffer, 0, buffer.Length);
        }
    }
}

我认为这部分是错误的DATASIXTEEN[i] = stream32.Read(buffer, 0, buffer.Length);,但我不知道如何纠正它。

您会给我一些建议或使用 Wave16ToFloatProvider 的代码吗?

或者我会问你如何在没有 Wave16ToFloatProvider 的情况下进行转换?

4

1 回答 1

4

from 的返回值Stream.Read是读取的字节数的计数,而不是您所追求的。您想要的数据在缓冲区中,但每个 32 位样本分布在 4 个 8 位字节中。

有多种方法可以将数据获取为 32 位浮点数。

第一种是使用ISampleProvider将数据转换为浮点格式并提供读取该格式数据的简单方法:

WaveFileReader reader = new WaveFileReader("wavetest.wav");
ISampleProvider provider = new Pcm16BitToSampleProvider(reader);

int blockSize = 2000;
float[] buffer = new float[blockSize];

// Read blocks of samples until no more available
int rc;
while ((rc = provider.Read(buffer, 0, blockSize)) > 0)
{
    // Process the array of samples in here.
    // rc is the number of valid samples in the buffer
    // ....
}

或者,有一种方法WaveFileReader可以让您直接读取浮点样本。缺点是它一次读取一个样本组(即每个通道一个样本 - 一个用于单声道,两个用于立体声),这可能很耗时。在大多数情况下,读取和处理数组更快。

WaveFileReader reader = new WaveFileReader("wavetest.wav");
float[] buffer;

while ((buffer = reader.ReadNextSampleFrame()) != null)
{
    // Process samples in here.
    // buffer contains one sample per channel
    // ....
}
于 2013-11-08T22:53:33.497 回答