如何在java中使用一个音序器实现多个节奏

时间:2015-02-11 15:11:18

标签: java audio midi

我一直在研究Java中的节拍器音乐应用程序,我偶然发现了一个并发症。请考虑以下代码:https://community.oracle.com/thread/2135272。这里的实现类似于我为获得多个节奏所做的工作。我遇到的唯一问题是它让事情变得有些混乱,我希望也许有人可能会提供另一种方法来获得多个节奏,最好是使用一个音序器。

import java.util.*;
import javax.swing.*;
import javax.sound.midi.*; 

public class MetronomeTestApplet extends JApplet
{
     public void init()
     {
          MetronomeTest metTest = new MetronomeTest();
          metTest.play();
     }
}

class MetronomeTest
{
     Sequencer sequencer1=null;
     Sequencer sequencer2=null;

     Sequence sequence1=null;
     Sequence sequence2=null;

     Track track1=null;
     Track track2=null;

     MidiEvent newEvent=null;

     int volume = 90;     
     int tempo     = 100;

     public MetronomeTest()
     {     
          try
          {     // SEQUENCER 1
               sequencer1 = MidiSystem.getSequencer();
               sequencer1.open();
               sequence1 = new Sequence(Sequence.PPQ, 16);
               track1 = sequence1.createTrack();

               ShortMessage instrumentMsg = new ShortMessage();
               instrumentMsg.setMessage(ShortMessage.PROGRAM_CHANGE, 0, 115, 0);          // 115 == woodblock
               track1.add(new MidiEvent(instrumentMsg, 0));

               // SEQUENCER 2
               sequencer2 = MidiSystem.getSequencer();
               sequencer2.open();
               sequence2 = new Sequence(Sequence.PPQ, 16);
               track2 = sequence2.createTrack();

               instrumentMsg = new ShortMessage();
               instrumentMsg.setMessage(ShortMessage.PROGRAM_CHANGE, 0, 117, 0);          // 117 == melodic tom
               track2.add(new MidiEvent(instrumentMsg, 0));
          }
          catch (Exception e) { e.printStackTrace(); }
     }

     public void destroy()
     {
          sequencer1.stop();
          sequencer1.close();

          sequencer2.stop();
          sequencer2.close();
     }

     public void play()
     {
          try
          {               
               // LOAD SEQUENCE 1               
               for (int i=0; i<4; i++)
               {
                    ShortMessage noteOnMsg = new ShortMessage();
                    noteOnMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, volume);
                    track1.add(new MidiEvent(noteOnMsg, 0 + 16*i));

                    ShortMessage noteOffMsg = new ShortMessage();
                    noteOffMsg.setMessage(ShortMessage.NOTE_OFF, 0, 60, volume);
                    track1.add(new MidiEvent(noteOffMsg, 16 + 16*i));
               }

               // LOAD SEQUENCE 2               
               for (int i=0; i<8; i++)
               {
                    ShortMessage noteOnMsg = new ShortMessage();
                    noteOnMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, volume);
                    track2.add(new MidiEvent(noteOnMsg, 0 + 8*i));

                    ShortMessage noteOffMsg = new ShortMessage();
                    noteOffMsg.setMessage(ShortMessage.NOTE_OFF, 0, 60, volume);
                    track2.add(new MidiEvent(noteOffMsg, 8 + 8*i));
               }

               // LOAD AND START SEQUENCERS
               sequencer1.setSequence(sequence1);
               sequencer1.setTempoInBPM(tempo);
               sequencer1.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);

               sequencer2.setSequence(sequence2);
               sequencer2.setTempoInBPM(tempo);
               sequencer2.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);

               sequencer1.start();
               sequencer2.start();
          }
          catch (Exception e) { e.printStackTrace(); }
     }
}

1 个答案:

答案 0 :(得分:1)

documentation说:

  

序列可以包含封装标准MIDI节奏变化消息的事件。当音序器处理这样的事件时,它会改变播放速度以反映指示的速度。