Audio 读取WAV文件时,数据ID打印为;事实“;而不是",;“数据”;
我是音频播放新手,花了一整天的时间阅读wav文件规范。我编写了一个简单的程序来提取文件的头,但是现在我的程序总是返回false,因为DataID一直以“事实”而不是“数据”的形式返回 我相信这可能发生的原因有几个Audio 读取WAV文件时,数据ID打印为;事实“;而不是",;“数据”;,audio,wav,Audio,Wav,我是音频播放新手,花了一整天的时间阅读wav文件规范。我编写了一个简单的程序来提取文件的头,但是现在我的程序总是返回false,因为DataID一直以“事实”而不是“数据”的形式返回 我相信这可能发生的原因有几个 我正在读取的文件的格式大小为18,而有效的PCM文件的格式大小应为16 我正在读取的文件的格式代码是6,这意味着它可能已被压缩 dataSize的值太小(只有4)。即使文件在通过VLC或Windows Media Player运行时有30秒的播放时间 我使用的代码如下: using
- 我正在读取的文件的格式大小为18,而有效的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。为什么会发生这种情况?RIFF规范不要求“数据”块跟随“fmt”块。您可能会看到一些文件在“fmt”块之后写入“pad”块,以确保页面对齐以获得更好的流 如您所述,格式代码还指示音频压缩类型。有效的格式代码是mmreg.h(在Windows上):(格式6是aLaw,实际上是一种压缩类型)
最好的方法是编写代码,读取块头,检查所需的类型,如果找不到要查找的内容,则跳过它跳到下一个块。感谢Ron的建议,我刚刚打印出了头,看到了事实,然后是数据。可以设置的填充量是否有限制?或者你能推荐更多的资源来帮助我解决这个问题吗?请参阅更新的答案。填充物真的没有限制。最安全的方法是准备好头字节,查看标记,如果不是您想要的,则执行文件搜索到块的末尾。谢谢Ron,感谢您的帮助。这应该足以解决这个问题。