2017-05-31 50 views
0

我正试图从midi文件的第一首曲目中提取旋律的速度,并将其应用于包含音符事件的曲目的其余部分。如何将从轨道1提取的速度应用于MIDI文件的其他轨道?

从根本上讲,我一直试图在noteOn()消息之后替换Thread.sleep()方法,该消息每次播放固定时间间隔的音符。因此我正在失去整个赛道的节奏。

我从以前提出的问题How does Midi TEMPO message apply to other tracks?的第一首曲目中成功提取节奏信息,但无法将其应用于其余曲目。

是否有一个特定的功能呢?我尝试搜索,但找不到一个。

这里是我的代码供参考。

 int trackNumber = 0; 

    for (Track track : sequence.getTracks()) { 

     trackNumber++;   
     System.out.println(); 
     for (int i=0; i < track.size(); i++) { 

      MidiEvent event = track.get(i); 
      MidiMessage message = event.getMessage(); 

      if (message instanceof MetaMessage) { 

      MetaMessage mm = (MetaMessage) message; 
      if(mm.getType()==SET_TEMPO){ 

       byte[] data = mm.getData(); 
       int tempo = (data[0] & 0xff) << 16 | (data[1] & 0xff) << 8 | (data[2] & 0xff); 
       int bpm = 60000000/tempo; 
      } 
      } 

      if (message instanceof ShortMessage) { 
       ShortMessage sm = (ShortMessage) message; 
       if (sm.getCommand() == NOTE_ON) { 

        int key = sm.getData1(); 
        int velocity = sm.getData2();      
        channels[0].noteOn(key,velocity); 
        Thread.sleep(280);//Pays all the note for fixed duration  
       } 
       else if (sm.getCommand() == NOTE_OFF) { 

        int key = sm.getData1(); 
        int velocity = sm.getData2(); 
        channels[0].noteOff(key); 

       } 
      } 
     } 

     System.out.println(); 
    } 
} 
+0

只需从第一个轨道克隆SetTempo事件并[add](https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/Track.html#add(javax.sound。 midi.MidiEvent))将实例复制到具有相同时间戳的其他轨道。 – Maxim

回答

0

多个曲目中的事件同时发生,因此您无法单独处理曲目。

你必须

  • 把所有事件到一个列表或者和自己所时间戳进行排序(但要确保使用相同的时间戳事件保持它们的顺序,所以使用稳定的排序算法);或
  • 具有每个轨道的当前位置,并且当确定哪个事件是下一个事件时,在所有轨道中搜索具有最小时间戳的尚未使用的事件。

请注意,速度可以在播放过程中更改,因此单个bpm值不足。请参阅How to correctly convert MIDI ticks to milliseconds?How can I parse a tempo of midi using Java?

+0

从我所了解的情况来看,在按照它们的时间戳值对事件进行排序后,我应该将从它评估的增量时间值作为参数传递给'Thread.sleep(millisec)'函数。让我知道这是你一直试图解释的。谢谢。 – BitWriter

+0

滴答不是毫秒,而且滴答时间在单个轨道中的事件之间。排序后,您必须再次计算相邻事件之间的计时器间隔。 –