读取 WAV 文件时,dataID 打印为 "fact" 而不是 "data"
When reading a WAV file, dataID is printed as "fact" and not "data"
我是音频播放的新手,花了一天时间阅读了 wav 文件规范。我写了一个简单的程序来提取文件的 header 但现在我的程序总是 returns false 因为 DataID 保持 returning 为 "fact" 而不是 "data".
我认为这可能发生有几个原因。
我正在阅读的文件的格式大小为 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
导致方法 return 错误。为什么会这样?
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
你最好的办法是编写读取块 headers 的代码,检查你想要的类型,如果你找不到你要找的东西,就跳过它到下一个块。
我是音频播放的新手,花了一天时间阅读了 wav 文件规范。我写了一个简单的程序来提取文件的 header 但现在我的程序总是 returns false 因为 DataID 保持 returning 为 "fact" 而不是 "data".
我认为这可能发生有几个原因。
我正在阅读的文件的格式大小为 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
导致方法 return 错误。为什么会这样?
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
你最好的办法是编写读取块 headers 的代码,检查你想要的类型,如果你找不到你要找的东西,就跳过它到下一个块。