【问题标题】:Decode MIDI variable length field解码 MIDI 可变长度字段
【发布时间】:2014-07-12 09:31:15
【问题描述】:

如何解码 MIDI 中的可变长度字段?在 [1] 中找到的描述仅给出了一些示例,而没有提及如果设置了最高有效位会发生什么。这是我当前的代码:

uint32_t MuStudio::MIDI::FileReader::varfieldGet()
    {
//  Note: always swap bytes on return since the loop reads in LE fashion since it
//  it cannot be known a priori how many bytes to read

    uint32_t ret=0;
    uint8_t byte_in;
    uint8_t k=0;
    while(!m_source.eof())
        {
        byte_in=m_source.byteGet();
        if(byte_in&0x80)
            {
            if(k==sizeof(ret))
                {break;}
        //  How to continue here?
            }
        else
            {return __builtin_bswap32(ret|(byte_in<<k));}
        }

    while(!m_source.eof() && byte_in&0x80)
        {byte_in=m_source.byteGet();}

    return __builtin_bswap32(ret);
    }

[1]http://www.music.mcgill.ca/~ich/classes/mumt306/midiformat.pdf

【问题讨论】:

    标签: midi decoding variable-length


    【解决方案1】:

    可变长度值不是小端而是大端,但这并不重要,因为您一次读取一个字节并以您的本机字节顺序构造结果。

    当您将一个字节与先前读取的位组合时,您必须移动先前的位,而不是当前字节。

    当设置了最高有效位时,您不必做任何特别的事情;当该位清除时,您必须停止:

    uint32_t varfieldGet()
    {
        uint32_t ret = 0;
        uint8_t byte_in;
    
        for (;;)
        {
            if (m_source.eof())
                // return error
            byte_in = m_source.byteGet();
            ret = (ret << 7) | (byte_in & 0x7f);
            if (!(byte_in & 0x80))
                return ret;
        }
    }
    

    【讨论】:

    • 如何处理ret中的溢出?
    • 这段代码没有。您可以更改 for 循环。
    • 终止条件是n_iter==sizeof(uint32_t)
    猜你喜欢
    • 1970-01-01
    • 2023-02-21
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2014-05-28
    • 1970-01-01
    • 2012-01-02
    相关资源
    最近更新 更多