【问题标题】:Encoding.ASCII.GetBytes issue with MatlabMatlab 的 Encoding.ASCII.GetBytes 问题
【发布时间】:2013-12-20 16:01:55
【问题描述】:

WriteWavHeader 函数实现了 WAV 标头。问题是当我尝试在 Matlab 中使用wavread 读取 WAV 文件时,我失败了。通过在wavread 中添加断点,我检查了尽管Matlab 可以很好地读取“WAVE”、“fmt”和“数据”标头(即ck.ID 等于'WAVE''fmt ' 和@ 987654327@ 分别在每次迭代中),它无法正确读取'end of file' 字符串。具体来说,ck.ID 等于一堆奇怪的 ASCII 字符。当我对ck.ID = 'end of file' 进行硬编码时,我设法读取了 wav 文件。有关如何解决此问题的任何想法?

static void WriteWavHeader(Stream stream, int dataLength)
    {
        using (var memStream = new MemoryStream(64))
        {
            int cbFormat = 18; //sizeof(WAVEFORMATEX)

            WAVEFORMATEX format = new WAVEFORMATEX()
            {
                wFormatTag = 1,
                nChannels = 1,
                nSamplesPerSec = 16000,
                nAvgBytesPerSec = 32000,
                nBlockAlign = 2,
                wBitsPerSample = 16,
                cbSize = 0
            };

            using (var binarywriter = new BinaryWriter(memStream))
            {
                //RIFF header
                WriteString(memStream, "RIFF");
                binarywriter.Write(dataLength + 8 + cbFormat + 8 + 4); //File size - 8

                WriteString(memStream, "WAVE");
                WriteString(memStream, "fmt ");
                binarywriter.Write(cbFormat);

                //WAVEFORMATEX
                binarywriter.Write(format.wFormatTag);
                binarywriter.Write(format.nChannels);
                binarywriter.Write(format.nSamplesPerSec);
                binarywriter.Write(format.nAvgBytesPerSec);
                binarywriter.Write(format.nBlockAlign);
                binarywriter.Write(format.wBitsPerSample);
                binarywriter.Write(format.cbSize);

                //data header
                WriteString(memStream, "data");
                binarywriter.Write(dataLength);

                memStream.WriteTo(stream);
                WriteString(memStream, "end of file");

            }
        }
    }

static void WriteString(Stream stream, string s)
    {
        byte[] bytes = Encoding.ASCII.GetBytes(s);
        stream.Write(bytes, 0, bytes.Length);

    }

【问题讨论】:

    标签: c# matlab ascii wav


    【解决方案1】:

    你在看这段代码吗(edit wavread 大约在第 208 行)?

    function [ck,msg] = read_ckinfo(fid)
    
    msg     = '';
    ck.fid  = fid;
    ck.Data = [];
    err_msg = getString(message('MATLAB:audiovideo:wavread:TruncatedChunkHeader'));
    
    [s,cnt] = fread(fid,4,'char');
    
    % Do not error-out if a few (<4) trailing chars are in file
    % Just return quickly:
    if (cnt~=4),
        if feof(fid),
            % End of the file (not an error)
            ck.ID = 'end of file';  % unambiguous chunk ID (>4 chars)
            ck.Size = 0;
        else
            msg = err_msg;
        end
        return
    end
    ...
    

    据我所知,没有称为“文件结尾”的有效 ID/块(它也不是四个字符长)。该函数只是将'end of file' 字符串作为标志返回给find_cktype 函数(参见第76 和99 行)。换句话说,您似乎正在将一串数据(您的“奇怪的 ASCII 字符”)写入您的 WAV 文件:

    WriteString(memStream, "end of file");
    

    在Matlab中检查文件结尾的方法是feof或检查fread返回的输出的长度。

    如果您想读取 WAV,我认为您将编写一些与您的标头内容相匹配的实际 WAV 数据。

    【讨论】:

    • 其实我加了一行 WriteString(memStream, "end of file");查看 Matlab 在其 wav 标头中是否需要“文件结尾”字符串。原始 wav 标头 (ccrma.stanford.edu/courses/422/projects/WaveFormat) 以数据结尾。我试过没有“行尾”ID的C#代码,但它在Matlab中也不起作用……
    • 它可能不起作用,因为您的文件不一致。你不能只有一个标题而没有数据。即使有标题和数据,一切都必须与文件中标题声明的内容相匹配。您提供的链接是一个很好的起点。您只需要确保一切都完美无缺。
    • 我很确定 C# 代码与链接是一致的,因为生成的 wav 文件在 VLC 播放器、Windows Media Player 和许多其他播放器中播放得很好。此外,如果我右键单击该文件以查看详细信息,则会显示正确的比特率和持续时间,这意味着 fmt 和数据头就可以了。我应该如何结束标题似乎只是一个问题......谢谢你的帮助!
    • 不,我根本不会这么认为。媒体播放器被设计成对损坏和格式错误的文件非常宽容。如果他们发现有问题,他们可以尝试很多不同的事情。然而,Matlab 通常没有充分的理由。 Matlab 的许多媒体阅读功能也是如此。检查所有部分的字节序是否正确。并尝试使用 HEX 查看器将代码中的输出文件与从质量编码器导出的文件(即,不仅仅是您在 Internet 上找到的一些随机 WAV)进行比较。另外,我是不是顺便回答了你原来的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多