2013-02-24 80 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