2013-02-24 81 views
2

我在從外部設備向我的音序器接收器傳輸數據時遇到了一些麻煩。我沒有任何問題傳輸給任何其他接收器。舉一個例子:Java MIDI外部設備傳輸到音序器的接收器

我有以下兩類:

public class TestData { 
    private Receiver receiver; 

    public TestData(Receiver receiver) 
    { 
     this.receiver = receiver; 
    } 

    public void sendTestData() throws InvalidMidiDataException 
    { 
     ShortMessage shortMessage = new ShortMessage(); 
     shortMessage.setMessage(ShortMessage.NOTE_ON, 0, 50, 127); 
     receiver.send(shortMessage, 123); 
     shortMessage.setMessage(ShortMessage.NOTE_OFF, 0, 50, 0); 
     receiver.send(shortMessage, 124); 
     shortMessage.setMessage(ShortMessage.NOTE_ON, 0, 51, 127); 
     receiver.send(shortMessage, 125); 
     shortMessage.setMessage(ShortMessage.NOTE_OFF, 0, 51, 0); 
     receiver.send(shortMessage, 126); 
    } 

} 

public class MidiInputReceiver implements Receiver { 
    public String name; 
    Map<Byte, String> commandMap = new HashMap<Byte, String>(); 

    public MidiInputReceiver(String name) { 
     this.name = name; 
     commandMap.put((byte)-112, "Note On"); 
     commandMap.put((byte) -128, "Note Off"); 
     commandMap.put((byte) -48, "Channel Pressure"); 
     commandMap.put((byte) -80, "Continuous Controller"); 
    } 
    public void send(MidiMessage msg, long timeStamp) { 
     System.out.println("midi received"); 
     System.out.println("Timestamp: " + timeStamp); 
     byte[] b = msg.getMessage(); 

     if(b[0] != -48){ 
      //System.out.println("Message length: " + msg.getLength()); 
      System.out.println("Note command: " + commandMap.get(b[0])); 
      System.out.println("Which note: " + b[1]); 
      System.out.println("Note pressure: " + b[2]); 
      System.out.println("---------------------"); 
     }else{ 
      //System.out.println("Message length: " + msg.getLength()); 
      System.out.println("Note command: " + commandMap.get(b[0])); 
      System.out.println("Note Pressure: " + b[1]); 
      System.out.println("---------------------"); 
     } 
    } 
    public void close() {} 
} 

這工作得很好:

sequencer = MidiSystem.getSequencer(); 
sequencer.open(); 
Sequence myseq = new Sequence(Sequence.PPQ, 10); 
Track newTrack = myseq.createTrack(); 
sequencer.setSequence(myseq); 
sequencer.setTickPosition(0); 
sequencer.recordEnable(newTrack, -1); 

TestData testData = new TestData(sequencer.getReceiver()) 
sequencer.startRecording(); 
testData.sendTestData(); 

這個作品,以及:

MidiDevice device; 
MidiDevice.Info[] infos; 
infos = MidiSystem.getMidiDeviceInfo(); 
device = MidiSystem.getMidiDevice(infos[0]); 
device.open(); 

Transmitter conTrans = device.getTransmitter(); 
conTrans.setReceiver(new MidiInputDevice("Test")); 

所以控制器沒有問題發送到我的自定義接收器。序列器的接收器從我的TestData類接收沒有問題。但以下(從我的外部控制器發送到我的音序器的接收器不起作用):

MidiDevice device; 
MidiDevice.Info[] infos; 
infos = MidiSystem.getMidiDeviceInfo(); 
device = MidiSystem.getMidiDevice(infos[0]); 
device.open(); 

sequencer = MidiSystem.getSequencer(); 
sequencer.open(); 
Sequence myseq = new Sequence(Sequence.PPQ, 10); 
Track newTrack = myseq.createTrack(); 
sequencer.setSequence(myseq); 
sequencer.setTickPosition(0); 
sequencer.recordEnable(newTrack, -1); 

Transmitter conTrans = device.getTransmitter(); 
conTrans.setReceiver(sequencer.getReceiver()); 
sequencer.startRecording(); 

有什麼,我失蹤了?

編輯: 好的,我可以看到該軌道實際上正在接收MidiEvents。我認爲問題是時機。記號的數字看起來非常高,所以當我回放時,我認爲它只是在等待一段非常長的時間來回放記錄開始時發生的事件。我認爲這與將我的設備同步到音序器有關,但我不確定我的SyncMode應該設置爲什麼。

回答

2

好吧我想出了一個方法來解決這個問題。這似乎運作良好。在播放之前,我會根據第一個打勾調整所有打勾。這需要爲每個軌道完成。

像這樣:

int eventSize = sequencer.getSequence().getTracks()[0].size(); 
MidiEvent firstEvent = sequencer.getSequence().getTracks()[0].get(0); 
long baseTime = firstEvent.getTick(); 

for(int i = 0; i < eventSize; i++){ 
    MidiEvent event = sequencer.getSequence().getTracks()[0].get(i); 
    event.setTick(event.getTick() - baseTime); 
} 
+0

+1,感謝..但是,你有沒有與此相關的 「問題」 的消息? – lhlmgr 2014-01-27 23:32:34