在读取WAV文件时,dataID被打印为"事实"而不是"数据"

时间:2015-05-20 17:38:41

标签: audio wav

我是音频播放的新手,并且花了一天时间阅读wav文件规范。我写了一个简单的程序来提取文件的标题但是现在我的程序总是返回false,因为DataID一直返回为"事实"而不是"数据"。

我认为可能会发生这种情况有几个原因。

  • 我正在阅读的文件格式大小为18,而this resource表示有效的PCM文件格式大小应为16.

  • 我正在阅读的文件的格式代码是6,这意味着它可能已被压缩。

  • dataSize的值太小(仅为4)。即使文件在通过VLC或Windows Media Player运行时有30秒的播放时间。

我使用的代码如下:

using (var reader = new BinaryReader(File.Open(wavFile, FileMode.Open)))
{
    // Read all descriptor info into variables to be passed
    // to an ASWAVFile instance.
    var chunkID       = reader.ReadBytes(4); // Should contain "RIFF"
    var chunkSize     = reader.ReadBytes(4);
    var format        = reader.ReadBytes(4); // Should contain "WAVE"

    var formatID      = reader.ReadBytes(4); // Should contain "fmt"
    var formatSize    = reader.ReadBytes(4); // 16 for PCM format.
    var formatCode    = reader.ReadBytes(2); // Determines linear quantization - 1 = PCM, else it has been compressed
    var channels      = reader.ReadBytes(2); // mono = 1, stereo = 2
    var sampleRate    = reader.ReadBytes(4); // 8000, 44,100 etc
    var byteRate      = reader.ReadBytes(4); // SampleRate * Channels * BitsPerSample / 8
    var blockAlign    = reader.ReadBytes(2); // Channels * BitsPerSample / 8
    var bitsPerSample = reader.ReadBytes(2); // If mono 8, if stereo 16 etc.

    var padding = byteToInt(formatSize);

    // Read any extra values so we can jump to the data chunk - extra padding should only be set here
    // if formatSize is 18
    byte[] fmtExtraSize = new byte[2];

    if (padding == 18)
    {
        fmtExtraSize = reader.ReadBytes(2);
    }


    // Read the final header information in, we can then set
    // other 
    var dataID   = reader.ReadBytes(4);      // Should contain "data"
    var dataSize = reader.ReadBytes(4);      // Calculated by Samples * Channels * BitsPerSample / 8

    // Check if the file is in the correct format
    if ( 
            System.Text.ASCIIEncoding.Default.GetString(chunkID)  != "RIFF" ||
            System.Text.ASCIIEncoding.Default.GetString(format)   != "WAVE" ||
            System.Text.ASCIIEncoding.Default.GetString(formatID) != "fmt"  ||
            System.Text.ASCIIEncoding.Default.GetString(dataID)   != "data"
        )
    {
        return false;
    }


    //file = new ASWAVFile();
}

如果我转储chunkID,format,formatID和dataID的值,我得到:

RIFF, WAVE, fmt, fact

导致该方法返回false。为什么会这样?

1 个答案:

答案 0 :(得分:2)

RIFF规范不要求'data'块跟随'fmt'块。您可能会看到一些文件在'fmt'块之后写入'pad'块以确保页面对齐以获得更好的流式传输。

http://en.wikipedia.org/wiki/WAV

如您所述,格式代码也表示音频压缩类型。有效的格式代码在mmreg.h中(在Windows上):(格式6是aLaw,实际上是压缩类型)。

http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/Docs/MMREG.H

最好的办法是编写读取块头的代码,检查所需的类型,如果找不到所需内容,则跳过它到下一个块。