解码MIDI可变长度字段

时间:2014-07-12 09:31:15

标签: midi decoding variable-length

如何解码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

1 个答案:

答案 0 :(得分:0)

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

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

当设置最重要的位时,您不必做任何特殊的事情;当该位清零时,您必须停止:

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;
    }
}