1

我有一个 .wav 单声道文件(16bit,44.1kHz),我使用下面的代码。如果我没有错,这会给我一个介于 -1 和 1 之间的值的输出,我可以应用 FFT(稍后转换为频谱图)。但是,我的输出与 -1 和 1 相差甚远。

这是我输出的一部分

7.01214599609375  
17750.2552337646  
8308.42733764648  
0.000274658203125  
1.00001525878906  
0.67291259765625  
1.3458251953125  
16.0000305175781  
24932  
758.380676269531  
0.0001068115234375    

这是我从另一篇文章
编辑 1 中获得的代码:

 public static Double[] prepare(String wavePath, out int SampleRate)
    {
        Double[] data;
        byte[] wave;
        byte[] sR = new byte[4];
        System.IO.FileStream WaveFile = System.IO.File.OpenRead(wavePath);
        wave = new byte[WaveFile.Length];
        data = new Double[(wave.Length - 44) / 4];//shifting the headers out of the PCM data;
        WaveFile.Read(wave, 0, Convert.ToInt32(WaveFile.Length));//read the wave file into the wave variable
        /***********Converting and PCM accounting***************/
       for (int i = 0; i < data.Length; i += 2)
        {
             data[i] = BitConverter.ToInt16(wave, i) / 32768.0;
        }


        /**************assigning sample rate**********************/
        for (int i = 24; i < 28; i++)
        {
            sR[i - 24] = wave[i];
        }
        SampleRate = BitConverter.ToInt16(sR, 0);
        return data;
    }  

编辑 2:我每第二个数字输出 0

0.009002685546875
0
0.009613037109375
0
0.0101318359375
0
0.01080322265625
0
0.01190185546875
0
0.01312255859375
0
0.014068603

4

1 回答 1

3

如果您的样本是 16 位(似乎是这种情况),那么您想要使用Int16. 样本数据的每 2 个字节是一个带符号的 16 位整数,范围为 -32768 .. 32767(含)。

如果要将有符号Int16的浮点值从 -1 转换为 1,则必须除以Int16.MaxValue + 1(等于 32768)。因此,您的代码变为:

for (int i = 0; i < data.Length; i += 2)
{
    data[i] = BitConverter.ToInt16(wave, i) / 32768.0;
}

我们在这里使用 32768,因为这些值是有符号的。

所以 -32768/32768 会给出 -1.0,而 32767/32768 会给出 0.999969482421875。

如果您使用 65536.0,那么您的值将仅在 -0.5 .. 0.5 范围内。

于 2013-07-01T15:37:59.187 回答