2011-08-04 12 views
8

私は自分のシンセサイザーをjavaで設計しましたが、今はMIDIキーボードと接続したいと思っています。下のクラスは、送信機を持つすべてのMIDIデバイスを検索します。それは正常に私のMIDIキーボードを見つける。私は可能なすべてを拾う必要があるように、各デバイスの各トランスミッタに自分のレシーバを追加します。すべてのヘルプドキュメントとjavaドキュメントを読むことから、TransmitterがMidiEventをReceiverに送信し、Receiverがsendメソッドでそれらを処理することが分かりました。だから私はReceiverを実装している自分自身の内部クラスを書き、sendメソッドで何も検出されなかったかどうかを確認するためにprintlnステートメントを使用しました。しかし、何も拾われません。このような単純なことをするのにはほとんど役に立たないようです。すべてのヘルプファイル、javadoc、フォーラムを見てきました。私は何とか見逃してしまったことが本当に明白なものでなければならないと確信しています。Javaキーボードからの入力を取得する

私のシンセサイザをインターフェイスシンセサイザと混同してはいけません。これはMIDIミキサーではありません。それは、合成アルゴリズムを使用し、再生方法を有する。基本的には、再生方法を呼び出す予定のノートをMIDIキーボードに送信するだけです。

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() {} 
    } 
} 

注:Java MIDI - getting data from piano?:私はすでにこれを見てきました 。

と、この:http://www.jsresources.org/examples/MidiInDump.html

インターフェース・シーケンサは、私も欲しいもののために複雑に道を見ました。

答えて

12

私はMidiDeviceのgetTransmittersは()現在すでに開いトランスミッタ、使用できませんを開くことになっている送信機のリストを返すように表示されていることを発見しました。新しいトランスミッタを開く方法は、getTransmitter()メソッドを使用することです。私はこれを行うには、あなたのコードを変更した:私のハードウェアでは

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() {} 
    } 
} 

を、コードが正しくMidiHandlerのインスタンスが作成された後に「MIDIを受信し、」プリントアウト(私は電源に接続、簡単なUSBのMIDIコントローラーを持っています)。

希望すると便利です。

+0

大変ありがとうございます!これは動作し、あまり複雑でないコードです。 – Jonathan

2

setRecceiver()を呼び出す前にデバイスを開く必要があることが判明しました。そうしないと、アプリケーションを最後に実行したときの受信者のsend()メソッドがすべてのガベージMIDIデータで呼び出されます。

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

受信者を追加する前にdevotedを開くことが重要です – codewandler

関連する問題