【问题标题】:Could read properly the data of WAV file可以正确读取WAV文件的数据
【发布时间】:2016-01-10 01:44:03
【问题描述】:

我正在尝试阅读wav file,如下所示

class Program
    {
        struct WavHeader
        {
            public int riffID; 
            public int size; 
            public int wavID;  
            public int fmtID; 
            public int fmtSize;
            public int format;
            public int channels; 
            public int sampleRate;
            public int bytePerSec; 
            public int blockSize;
            public int bit; 
            public int dataID; 
            public int dataSize; 
        }
        static void Main(string[] args)
        {
            WavHeader Header = new WavHeader();
            List<short> lDataList = new List<short>();
            List<short> rDataList = new List<short>();

            using (FileStream fs = new FileStream(@"D:\Test.wav", FileMode.Open, FileAccess.Read))
            using (BinaryReader br = new BinaryReader(fs))
            {
                try
                {                    
                    Header.riffID = br.ReadInt32();
                    Header.size = br.ReadInt32();
                    Header.wavID = br.ReadInt32();
                    Header.fmtID = br.ReadInt32();
                    Header.fmtSize = br.ReadInt32();
                    Header.format = br.ReadUInt16();
                    Header.channels = br.ReadUInt16();
                    Header.sampleRate = br.ReadInt32();
                    Header.bytePerSec = br.ReadInt32();
                    Header.blockSize = br.ReadInt16();
                    Header.bit = br.ReadInt16();

                    if (Header.fmtSize == 18)
                    {
                        // Read any extra values
                        int fmtExtraSize = br.ReadInt16();
                        br.ReadBytes(fmtExtraSize);
                    }
                    Header.dataID = br.ReadInt32();
                    Header.dataSize = br.ReadInt32();

                    int bytesForSamp = Header.bit / 8;
                    int samps = Header.dataSize / bytesForSamp;


                    for (int i = 0; i < samps; i++)
                    {
                        lDataList.Add((short)br.ReadUInt16());
                        rDataList.Add((short)br.ReadUInt16());
                    }


                }
                finally
                {
                    if (br != null)
                    {
                        br.Close();
                    }
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            }
        }
    }

但是在

处出现运行时错误
lDataList.Add((short)br.ReadUInt16());
rDataList.Add((short)br.ReadUInt16());

{“无法在流结束后读取。”}

我已经看到了这个SO Q/A 并尝试按照要求进行调整,但返回浮动。

【问题讨论】:

    标签: c# audio


    【解决方案1】:

    在这里您正确计算了每个样本的字节数和样本数:

    int bytesForSamp = Header.bit / 8;
    int samps = Header.dataSize / bytesForSamp;
    

    但在这里您假设该文件有 2 个通道和 16 位样本:

    for (int i = 0; i < samps; i++)
    {
        lDataList.Add((short)br.ReadUInt16());
        rDataList.Add((short)br.ReadUInt16());
    }
    

    如果文件实际上有 8 位样本和/或只有 1 个通道,则此循环会尝试在某个点读取输入文件之外的内容。 您要么必须断言,在读取标头后文件实际上是 16 位 2ch,要么通过根据波形文件标头中指定的每个样本的位数和通道正确读取来正确处理文件。

    【讨论】:

    • 它有 16 位但有 1 个通道..你是对的..那么如何处理呢?
    • 作为一个快速修复,仅对于 this 特殊情况,您可以这样做: unsigned short data = br.ReadUInt16(); lDataList.Add(数据); rDataList.Add(数据);将数据复制到两个通道。但是您必须在生产代码中正确处理所有情况(1 到 n 个通道,n 位样本大小)。或者,如果 wav 文件具有未处理的属性,则会显示错误消息
    • 正确,我就是这么做的。
    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2013-11-29
    相关资源
    最近更新 更多