如何使用 Java 在 Midi 文件中列出乐器名称?

Posted

技术标签:

【中文标题】如何使用 Java 在 Midi 文件中列出乐器名称?【英文标题】:How to list instrument names in a Midi file with Java? 【发布时间】:2019-04-13 04:04:57 【问题描述】:

我使用下面的代码来播放一个midi文件,但是我找不到使用的乐器列表:

      try
      
        Sequence sequence=MidiSystem.getSequence(file);                                  // From file

        int trackNumber=0;
        for (Track track : sequence.getTracks())
        
          trackNumber++;
          System.out.println("Track "+trackNumber+": size = "+track.size());
          System.out.println();
          for (int i=0;i<track.size();i++)
          
            MidiEvent event=track.get(i);
            System.out.print("@"+event.getTick()+" ");
            if (message instanceof ShortMessage)
            
              ShortMessage sm=(ShortMessage)message;
              System.out.print("Channel: "+sm.getChannel()+" "+new String(sm.getMessage())+" | ");
            
            else Out("Other message: "+message.getClass());
          
          System.out.println();
        

        Sequencer sequencer=MidiSystem.getSequencer();
        sequencer.open();
        sequencer.setSequence(sequence);
        sequencer.start();                                                                               
      
      catch (Exception e)  e.printStackTrace(); 

我做了一些搜索,有类似的问题,但没有一个有直接的答案,我只想列出文件中使用的乐器,例如钢琴,鼓......我知道信息隐藏在消息中[也许被称为“程序”?! ],但我就是找不到。

【问题讨论】:

试试getCommand() 你检查过getSoundbank()返回的Soundbank对象吗?它有一个Instrument 对象列表。 对于缓存通道,getCommand() 将返回 192,144,128,144,128 ... 我知道 Soundbank 有一个可用乐器列表,但我怎么知道在我的特定声音文件中使用了哪些乐器? 【参考方案1】:

这是答案,我终于想通了:

Instrument instruments[];
Soundbank sb=synthesizer.getDefaultSoundbank();
if (sb!=null) instruments=synthesizer.getDefaultSoundbank().getInstruments();

...

      try
      
        Sequence sequence=MidiSystem.getSequence(file);                                  // From file

        int trackNumber=0;
        for (Track track : sequence.getTracks())
        
          System.out.print("Track "+(trackNumber++)+" : ");
          MidiEvent event=track.get(0);
          MidiMessage message=event.getMessage();
          if (message instanceof ShortMessage)
          
            ShortMessage sm=(ShortMessage)message;
            if (sm.getCommand()==192) Out("sm.getChannel()="+sm.getChannel()+"  sm.getData1()="+sm.getData1()+"  "+instruments[sm.getData1()]);
          
        

输出如下所示:

Track 0 : sm.getChannel()=0  sm.getData1()=0  Instrument: Piano 1      bank #0 preset #0
Track 1 : sm.getChannel()=1  sm.getData1()=16  Instrument: Organ 1      bank #0 preset #16
Track 2 : sm.getChannel()=2  sm.getData1()=56  Instrument: Trumpet      bank #0 preset #56
Track 3 : sm.getChannel()=3  sm.getData1()=25  Instrument: Steel-str.Gt bank #0 preset #25

【讨论】:

以上是关于如何使用 Java 在 Midi 文件中列出乐器名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java MIDI 程序中更改乐器

在音轨播放期间更改乐器 - MIDI/Java

Java MIDI - ControllerEventListener(如何更改乐器)

如何读取 MIDI 文件、更改其乐器并将其写回?

如何使用 Python 中的长笛乐器从音符制作 MIDI 文件(music21 库)

如何从 DryWetMidi 库中的特定 MIDI 文件块中获取程序/乐器标题?