2016-01-05 23 views
5

ho sbattere la testa su questo per tutto il giorno, leggere tutto quello che riesco a trovare, ha seguito la fonte JDK intorno, senza fortuna nel trovare i dettagli scabrosi su COME o DOVE sguardi java ottenere dati su un dispositivo midi e determina cosa è cosa.MIDI OUT trasmettitore non disponibili

Sto provando a catturare i messaggi midi attraverso la mia porta NI Audio 8 DJ MIDI IN, ma, java non sta "vedendo" la porta MIDI IN, ma solo l'uscita, che ho usato con successo per inviare midi con. Ottengo anche gli stessi risultati con un dispositivo midi USB UNO M-Audio: MidiSystem.getMidiDeviceInfo() solo "vede" la porta di uscita.

Ho verificato il funzionamento della porta MIDI IN con:

amidi -p hw:2,0 -d 

e inviandolo alcuni segnali. Funziona bene.

getMaxTransmitters() restituisce zero. MidiSystem.getMidiDeviceInfo() mostra solo una voce per entrambi i dispositivi: Audio8DJ [hw:2,0] o Interface [hw:2,0]

Il seguente codice funziona bene per un ricevitore e ritengo è solo i bit devo verificare che getTransmitter() afferra la porta, poiché funziona solo per l'altro e tutto funziona bene, fino a ottenere un'eccezione MidiUnavailableException/Transmitter non disponibile.

Ho anche preso la trappola getMaxReceivers() perché stavo solo cercando di vedere se il dispositivo offriva solo una voce e la risolveva, ma no.

public static Transmitter getMidiIn() { 
    if (midiIn == null){ 
     devices = MidiSystem.getMidiDeviceInfo(); 
     for(MidiDevice.Info info: devices){ 
      System.out.println("device class " + info.getClass()); 
      MidiDevice device; 
      try{ 
       device = MidiSystem.getMidiDevice(info); 
       if (info.toString().equals("Audio8DJ [hw:2,0]")){ 

        if (device.getMaxTransmitters() != 0){ 
         try{ 
          device.open(); 
          System.out.println("max transmitters:" + device.getMaxTransmitters()); 
          midiIn = device.getTransmitter(); 
          System.out.println("Found a transmitter: "+ midiIn); 
          break; 
         } catch (Exception e){ 
          e.printStackTrace(); 
         } 
        } 
       } 
      } catch (MidiUnavailableException e1){ 
       e1.printStackTrace(); 

      } 
     } 
    } 
    return midiIn; 
} 

Quindi la cosa che mi sta facendo qui è questa: le liste alsa una sola voce nel amidi -l e quando ho specificare che come porto per scaricare, funziona benissimo. Java ottiene la stessa immissione di testo e non riesce a riordinare il MIDI IN, assegnandogli la classe com.sun.media.sound.MidiOutDeviceProvider, quindi mi chiedo come fa, o dove Java capisce cosa un dispositivo ha da offrire e perché non lo vede? porta di input che Alsa sta vedendo.

Sto codificando con eclissi Versione: 3.8.1 IDE con JDK1.6, su un SO linux mint,.

Sarò felice di fornire qualsiasi richiesta. Grazie per aver letto!

+2

Solo un pensiero casuale ... hai provato a eseguirlo usando 'sudo'? (Ad esempio, 'sudo java your.class.name' sulla riga di comando.) Ho riscontrato problemi in cui è necessario essere root per manipolare alcuni dispositivi, quindi potrebbe valere la pena provare. –

+1

Ci ho pensato, e sono aperto al suggerimento, ma, sono stato titubante a provare per due motivi che circondano la reazione istintiva che eseguire applicazioni complesse come root è pericoloso: 1) poiché può ottenere Porta MIDI OUT senza problemi, quindi preferirei scoprire quale file java sta accedendo e risolvere il problema. 2) non dovrebbe essere eseguito come root e se eseguirlo come root lo risolve, sono tornato allo stesso problema di capire quale file ha il problema di accesso. –

+1

Grazie ancora per l'aiuto Mike, mi hai fatto andare nella giusta direzione. Si prega di vedere la mia risposta qui sotto. –

risposta

3

La soluzione per vedere il trasmettitore java era nella versione di JDK utilizzata, anche se sfortunatamente in questo momento, non ho una risposta su perché l'errore ha funzionato e si adatta alle mie esigenze per ora. Se trovo la risposta, modifico questa risposta.

Delle tre versioni che stavo passando tra test, jdk1.8.0_60, jdk1.7.0_80, jdk1.6.0_45, 1.7 non ho riscontrato l'errore e ho ottenuto con successo un trasmettitore dal mio dispositivo. Ho trovato questo, e che i privilegi non erano la causa del mio problema specifico, compilando e eseguendo un codice I found adatto per l'esecuzione da riga di comando che tenta di ottenere il trasmettitore, stampa i dati midi inviati ad esso, e modificato un po ' ...

import javax.sound.midi.MidiDevice; 
import javax.sound.midi.MidiMessage; 
import javax.sound.midi.MidiSystem; 
import javax.sound.midi.MidiUnavailableException; 
import javax.sound.midi.Receiver; 

public class MidiInputTest { 

    public MidiDevice  input; 
    public MidiDevice  output; 

    public static void main(String[] args) { 
     new MidiInputTest().start(); 
    } 


    public void start() { 
     init(); // initialize your midi input device 
       // system dependent 


     try { 
      output.open(); // From midi device 
      MyReceiver myrcvr = new MyReceiver(); 
      MidiSystem.getTransmitter().setReceiver(myrcvr); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      System.exit(0); 
     } 

    } 

    private class MyReceiver implements Receiver { 
     Receiver rcvr; 
     public MyReceiver() { 
      try { 
       this.rcvr = MidiSystem.getReceiver(); 
      } catch (MidiUnavailableException mue) { 
       mue.printStackTrace(); 
      } 
     } 

     @Override 
     public void send(MidiMessage message, long timeStamp) { 
      byte[] b = message.getMessage(); 
      if (b[0] != (byte)254) { 
       System.out.println((b[0] & 0xff) + " " + (b[1] & 0xff)); 
      } 
      //rcvr.send(message, timeStamp); // will send out what ever you receive 
     } 

     @Override 
     public void close() { 
      rcvr.close(); 
     } 
    } 
    public void init() { 

     MidiDevice.Info[] devices; 

     devices = MidiSystem.getMidiDeviceInfo(); 
     try{ 

      for (MidiDevice.Info info: devices) { 
       MidiDevice device; 
       device = MidiSystem.getMidiDevice(info); 
       System.out.println("MidiDevice.Info="+info + "\n" + "maxTransmitters="+device.getMaxTransmitters()); 

       // I put the specific device I want to connect to behind an if gate here to avoid connecting to something I do not 

       if (info.toString().equals("Interface [hw:2,0,0]") && device.getMaxTransmitters() != 0) { 
        System.out.println(" Name: " + info.toString() + 
          ", Decription: " + 
          info.getDescription() + 
          ", Vendor: " + 
          info.getVendor()); 

        output = MidiSystem.getMidiDevice(info); 

        if (! output.isOpen()) { 
         output.open(); 
        } 
       } 
      } 
     } catch (MidiUnavailableException mue) { 
        mue.printStackTrace(); 
     } 
    } 
} 

per eseguire questo dalla riga di comando scegliere una versione del JDK è stato installato, compilare ed eseguire con queste versioni specifiche sostituendo jdk1.7.0_80 per la distro si desidera testare.

/opt/java-jdk/jdk1.7.0_80/bin/javac MidiInputTest.java 
/opt/java-jdk/jdk1.7.0_80/bin/java -cp . MidiInputTest 

Anche se non ho potuto verificare che, Java suono è apparentemente responsabile di capire che cosa è disponibile per l'uso di Java dall'attuale architettura MIDI.

Grazie Mike Harris per avermi inviato il giusto percorso di test sulla riga di comando e jim829 su java-forums.org per il codice di esempio per la riga di comando.