2011-08-04 38 views
8

Tôi đã thiết kế bộ tổng hợp của riêng mình trong java và bây giờ tôi muốn kết nối nó với bàn phím midi. Lớp của tôi bên dưới tìm kiếm thông qua tất cả các thiết bị midi có bộ phát. Nó tìm thấy thành công bàn phím midi của tôi. Tôi thêm máy thu của riêng mình vào mỗi bộ phát cho mỗi thiết bị để nó nhận mọi thứ có thể. Từ đọc tất cả các tài liệu trợ giúp và tài liệu java tôi biết rằng một máy phát gửi MidiEvents đến một máy thu mà sau đó xử lý chúng bằng phương thức gửi. Vì vậy, tôi đã viết lớp bên trong của riêng tôi thực hiện nhận và chỉ cần sử dụng một tuyên bố println để kiểm tra xem có bất cứ điều gì được phát hiện ở tất cả trong phương thức gửi. Tuy nhiên không có gì được chọn cả. Dường như có rất ít sự giúp đỡ để làm một điều đơn giản như vậy và tôi đã xem xét mọi tập tin trợ giúp, javadoc và diễn đàn. Tôi chắc chắn nó phải là một cái gì đó thực sự rõ ràng tôi đã bằng cách nào đó bị mất.Java nhận đầu vào từ bàn phím MIDI

Bộ tổng hợp của tôi không được nhầm lẫn với giao diện Bộ tổng hợp và nó không phải là thiết bị midi. Nó sử dụng một thuật toán tổng hợp và có một phương pháp phát lại. Về cơ bản tôi chỉ cần có được bàn phím midi gửi một lưu ý về sự kiện mà sẽ gọi phương thức phát lại.

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

LƯU Ý: Tôi đã thấy điều này: Java MIDI - getting data from piano?.

và điều này: http://www.jsresources.org/examples/MidiInDump.html

giao diện Sequencer nhìn cách phức tạp cho những gì tôi cũng muốn.

Trả lời

12

Tôi đã phát hiện ra rằng MidiDevice getTransmitters() xuất hiện trở lại danh sách các hiện đã mở phát, không phát được sẵn sẽ được mở. Tôi tin rằng cách để mở một máy phát mới là thông qua phương thức getTransmitter(). Tôi đã sửa đổi mã của bạn để làm điều này:

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

Mở phần cứng của tôi (Tôi có một đơn giản điều khiển USB MIDI cắm vào), mã in một cách chính xác ra "midi nhận" sau khi một thể hiện của MidiHandler được tạo ra.

Hy vọng điều này sẽ hữu ích!

+0

Cảm ơn rất nhiều! Điều này không hoạt động và ít mã phức tạp hơn. – Jonathan

2

Tôi thấy rằng bạn phải mở thiết bị trước khi gọi phương thức setRecceiver(), nếu không phương thức send() của người nhận sẽ được gọi với bất kỳ dữ liệu MIDI rác nào từ lần cuối cùng bạn chạy ứng dụng.

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

quan trọng của nó để mở deviced trước khi thêm người nhận – codewandler

Các vấn đề liên quan