Java MIDI Sequence.getTracks() 错误编号



我正在尝试获取 MIDI 序列的音轨数量:

File file = new File(strSource);
Sequence sequence = MidiSystem.getSequence(file);
int numTracks = sequence.getTracks().length;

。其中 strSource 是我的.mid文件的完整路径+文件名。numTracks 是 1,但.mid文件有 16 个音轨(当我在另一个 MIDI 编辑器中打开它时可以看到)。文件类型为 0。

我在某处读到,Type-0 文件不能在同一频道上有多个轨道。在这种情况下,所有轨道都强制进入单个轨道。这是对的吗?我怎样才能避免这种情况?

看来你是对的,Type-0 文件在一个文件中包含多个轨道。在这里,您有一些信息。

无法从类型 0 文件中提取每个单独的轨道。

检查 MIDI 文件类型,如果外部 MIDI 编辑器可以检测到多个音轨,则它可以是类型 1 或类型 2 文件,即使扩展名不匹配。

我用十六进制工具查看了该文件......它实际上只有一条轨道。

另一个编辑器自行创建多个轨道。它似乎搜索程序更改消息,然后将事件放入新轨道。

我编写了一个小函数,可以将类型 # 0 序列转换为类型 # 1 序列

/**
 * Make multiple tracks from file0 track
 * @param in : Sequence with single track
 * @return Multiple track sequence
 */
private Sequence extractFile0Tracks (Sequence in) throws InvalidMidiDataException
{
    Track inTrack = in.getTracks()[0];
    HashMap<Integer, ArrayList<MidiEvent>> msgMap = new HashMap<>();
    // Distribute events per channel to ArrayList map
    for (int i = 0; i < inTrack.size(); i++)
    {
        MidiEvent event = inTrack.get(i);
        MidiMessage message = event.getMessage();
        if (message instanceof ShortMessage)
        {
            ShortMessage sm = (ShortMessage) message;
            int channel = sm.getChannel() + 1;
            ArrayList<MidiEvent> msgList = msgMap.computeIfAbsent(channel, k -> new ArrayList<>());
            msgList.add(event);
        }
    }
    // Create sequence with multiple tracks
    Sequence newSeq = new Sequence(in.getDivisionType(), in.getResolution());
    for (ArrayList<MidiEvent> msgList : msgMap.values())
    {
        Track tr = newSeq.createTrack();
        for (MidiEvent m1 : msgList)
            tr.add(m1);
    }
    return newSeq;
}

相关内容

  • 没有找到相关文章

最新更新