2011-08-04 16 views
8

Kendi sentezleyicimi java'da tasarladım ve şimdi bir midi klavye ile bağlamak istiyorum. Aşağıdaki sınıfım, vericilere sahip tüm midi cihazlarda arama yapıyor. Midi klavyemi başarıyla bulur. Her cihaz için her alıcıya kendi alıcılarımı ekliyorum, böylece mümkün olan her şeyi almalıyım. Tüm yardım belgelerini ve java dokümanı okudum. Bir Vericinin MidiEvent'leri bir Alıcıya gönderdiklerini biliyorum. Bu yüzden kendi iç sınıfa Uygulamamı yazdım ve gönderim yönteminde hiç bir şey olup olmadığını kontrol etmek için bir println ifadesi kullandım. Ancak hiçbir şey alınmaz. Böyle basit bir şey yapmak için çok az yardım var gibi görünüyor ve her yardım dosyasına, javadoc ve foruma baktım. Eminim bir şekilde kaçırdığım bir şey olmalı.Java, MIDI klavyeden giriş alıyor

Sentezleyicim, Synthesizer arabirimi ile karıştırılmamalıdır ve bir midi aracı değildir. Bir sentez algoritması kullanır ve bir oynatma yöntemine sahiptir. Temel olarak, sadece midi klavyenin çalma yöntemini çağırmaya yönelik bir nota göndermesi gerekiyor.

import javax.sound.midi.*; 
import java.util.ArrayList; 
import java.util.List; 
import java.io.*; 
public class MidiHandler 
{ 
    //ArrayList of MidiDevices 
    private ArrayList<MidiDevice> devices = new ArrayList<MidiDevice>(); 

    public MidiHandler() 
    { 
     MidiDevice device; 
     MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); 
     for (int i = 0; i < infos.length; i++) { 
      try { 
       device = MidiSystem.getMidiDevice(infos[i]); 
       //does the device have any transmitters? 
       if (device.getTransmitters().size() > 0) { 
        //if it does, add it to the device list 
        System.out.println(infos[i] + ": " + device.getTransmitters().size()); 
        devices.add(device); 
       } 
      } catch (MidiUnavailableException e) {} 
     } 
     //if any transmitting devices were found 
     if(devices.size()>0) { 
      //for each device 
      for(int i = 0; i<devices.size(); i++) { 
       try { 
        //get all transmitters 
        List<Transmitter> transmitters = devices.get(i).getTransmitters(); 
        //and for each transmitter 
        for(int j = 0; j<transmitters.size();j++) { 
         //create a new receiver 
         transmitters.get(i).setReceiver(
          //using my own MidiInputReceiver 
          new MidiInputReceiver(devices.get(i).getDeviceInfo().toString()) 
         ); 
        } 
        //open each device 
        devices.get(i).open(); 
        //if code gets this far without throwing an exception 
        //print a success message 
        System.out.println(devices.get(i).getDeviceInfo()+" Was Opened"); 
       } catch (MidiUnavailableException e) {} 
      } 
     } 
    } 
    //tried to write my own class. I thought the send method handles an MidiEvents sent to it 
    public class MidiInputReceiver implements Receiver { 
     public String name; 
     public MidiInputReceiver(String name) { 
      this.name = name; 
     } 
     public void send(MidiMessage msg, long timeStamp) { 
      System.out.println("midi received"); 
     } 
     public void close() {} 
    } 
} 

NOT: Ben bunu önceden görmüştür: Java MIDI - getting data from piano?.

ve bu: http://www.jsresources.org/examples/MidiInDump.html

arayüz Sequencer Ben de istediğim için karmaşık yol görünüyordu.

cevap

12

Ben MidiDevice getTransmitters() anda zaten açık vericiler, mevcut değil açılacak olan vericiler listesini döndürmek için görünür olduğunu tespit ettik. Yeni bir verici açmanın yolunun getTransmitter() yöntemi ile olduğuna inanıyorum. Bunu yapmak için kodunuzu değiştirdik: Benim donanım üzerinde

import javax.sound.midi.*; 
import java.util.ArrayList; 
import java.util.List; 
import java.io.*; 
    public class MidiHandler 
{ 

    public MidiHandler() 
    { 
     MidiDevice device; 
     MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); 
     for (int i = 0; i < infos.length; i++) { 
      try { 
      device = MidiSystem.getMidiDevice(infos[i]); 
      //does the device have any transmitters? 
      //if it does, add it to the device list 
      System.out.println(infos[i]); 

      //get all transmitters 
      List<Transmitter> transmitters = device.getTransmitters(); 
      //and for each transmitter 

      for(int j = 0; j<transmitters.size();j++) { 
       //create a new receiver 
       transmitters.get(j).setReceiver(
         //using my own MidiInputReceiver 
         new MidiInputReceiver(device.getDeviceInfo().toString()) 
       ); 
      } 

      Transmitter trans = device.getTransmitter(); 
      trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo().toString())); 

      //open each device 
      device.open(); 
      //if code gets this far without throwing an exception 
      //print a success message 
      System.out.println(device.getDeviceInfo()+" Was Opened"); 


     } catch (MidiUnavailableException e) {} 
    } 


} 
//tried to write my own class. I thought the send method handles an MidiEvents sent to it 
public class MidiInputReceiver implements Receiver { 
    public String name; 
    public MidiInputReceiver(String name) { 
     this.name = name; 
    } 
    public void send(MidiMessage msg, long timeStamp) { 
     System.out.println("midi received"); 
    } 
    public void close() {} 
    } 
} 

, kodu doğru MidiHandler bir örneği oluşturulduktan sonra "midi alındı" yazdırır (ı takılı basit bir USB MIDI kontrolör var).

Bu yardımcı olur umarız!

+0

Mükemmel teşekkürler çok! Bu çalışır ve daha az kıvrık kod da. – Jonathan

2

Seni setRecceiver() çağırmadan önce cihazı açmak zorunda olduğunu tespit ettik aksi alıcının gönderme() yöntemi uygulamayı koştu son kez herhangi çöp MIDI verileri ile çağrılır.

device.open(); 

Transmitter trans = device.getTransmitter();  
// set new receiver after opening so that the input buffer will be flushed 
trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo().toString())); 
+0

alıcısını eklemeden önce açılmasını önemli – codewandler