如何使用C#和NAudio将[] Int16转换为[] float?

时间:2013-11-08 19:53:35

标签: c# audio type-conversion wav naudio

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

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

现在我正在尝试将[] 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的情况下进行转换?

1 个答案:

答案 0 :(得分:3)

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
    // ....
}