2013-02-24 1 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. Я думаю, что речь идет о сроках. Номера тиков выглядят очень высокими, поэтому, когда я иду играть, я думаю, что он просто ждет действительно и очень долго, чтобы воспроизвести событие, которое произошло в начале записи. Я думаю, что это имеет какое-то отношение к синхронизации моего устройства с моим секвенсором, но я не уверен, что должны быть установлены мои SyncModes.

ответ

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