4 Replies Latest reply: Apr 12, 2013 7:30 AM by PhHein RSS

    Midi Keyboard Delay

    977815
      I've a project I'm working on that requires me to play notes from my Midi (USB) Keyboard. I'm new to java midi so I've written the sample code below which works (ie I press a key and I hear a note being played) however there is a delay between me holding down the key and the note being played which varies depending on the environment. If I use a "Run" configuration in Eclipse with a JRE of "JavaSE-1.6" then the delay is about 250ms, but if I run it from the command line then the delay is almost a whole second.

      I'm using Win7 64bit. Command line environment is as follows:
      java -version
      java version "1.7.0_05"
      Java(TM) SE Runtime Environment (build 1.7.0_05-b06)
      Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
      The Keyboard is an 37 key Evolution eKeys.
      import javax.sound.midi.*;
      
      public class testMidi {
      
        public static void main(String[] args) throws Exception{
      
              Transmitter trans = MidiSystem.getTransmitter();
              Synthesizer synth = MidiSystem.getSynthesizer();
              trans.setReceiver(synth.getReceiver());
              synth.open();
              System.out.println("Play!");
              Thread.sleep(500000);  //Keeps Objects alive and playing
              trans.close();
              synth.close();
        }
      }
      Any suggestions? It may be relevant to ask what those default devices actually are because I'm having problems getting them working by name (ie finding the name by looping through MidiSystem.getMidiDeviceInfo() then asking for getTransmitter() doesn't work). I'm writing another post about that.

      Thank you!
      Peter

      Edited by: 974812 on 04-Dec-2012 01:26

      Edited by: 974812 on 04-Dec-2012 01:26
        • 1. Re: Midi Keyboard Delay
          977815
          As part of this investigation, I'm trying to work out which real world devices are talking to each other. However, because Transmitter doesn't seem to provide any way of linking back to it's parent, I'm finding that difficult. I wrote a quick test function to try and match the default transmitter against a Midi Device's transmitter, but it's not matching any of them.
          public static void test4() throws Exception {
            Transmitter defaultTrans = MidiSystem.getTransmitter();
            MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
            for (MidiDevice.Info inf:infos){
              MidiDevice device = MidiSystem.getMidiDevice(inf);
              try {
                Transmitter thisTrans = device.getTransmitter();
                if (thisTrans.equals(defaultTrans)) {
                  System.out.println ("Default Transmitter belongs to: " + inf.getName());
                }
              } catch (Exception e) {
                System.out.println (inf.getName() + " said: " + e.getMessage());
              }
            }
          }
          Result:
          Microsoft MIDI Mapper said: MIDI OUT transmitter not available
          Microsoft GS Wavetable Synth said: MIDI OUT transmitter not available
          USB MIDI keyboard said: MIDI OUT transmitter not available
          Java Sound Synthesizer said: MIDI OUT transmitter not available
          I this I've realised ithat getTransmitter() is not the same thing as getTransmitters().get(0). Am I right to say that getTransmitter returns the open transmitter that intrinsically belongs to that MidiDevice, and getTransmitters() is for returning already open transmitters that have been given to the device eg a Sequencer which can take both multiple transmitters and receivers?

          In any event if I say getTransmitters() on all MidiDevices in turn they all return zero length Lists.

          Next thing I'm trying is connecting all things that transmit to all things that receive in turn to see if any combination performs better than the default Transmitter / Synthesizer.

          Edited by: 974812 on 04-Dec-2012 04:53
          • 2. Re: Midi Keyboard Delay
            977815
            Wrote the following to wire up the keyboard to all available receivers. I got a variety of sounds out (using the USB Midi Keyboard) but none of them had what you would call a responsive feel - there was always some delay, although nothing as bad as the 1second I was seeing from the command line with JRE7 and the default devices.
            public static void test5() throws Exception {
              MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
              for (MidiDevice.Info inf:infos){
                MidiDevice transDevice = MidiSystem.getMidiDevice(inf);
                MidiDevice.Info[] infos2 = MidiSystem.getMidiDeviceInfo();
                for (MidiDevice.Info inf2:infos2){
                  MidiDevice recDevice = MidiSystem.getMidiDevice(inf2);
                  if (! transDevice.equals(recDevice)) {
                    try {
                      transDevice.open();
                      recDevice.open();
                      Transmitter tran = transDevice.getTransmitter();
                      Receiver rec = recDevice.getReceiver();
                      tran.setReceiver(rec);
                      System.out.println("Connected " + inf.getName() + "(" +
                         transDevice.getClass().getSimpleName() + 
                         ") to " + inf2.getName() + "(" + 
                         recDevice.getClass().getSimpleName() + ")" );
                      Thread.sleep(10000);
                      tran.setReceiver(null);
                    } catch (Exception e) {} finally {
                      transDevice.close();
                      recDevice.close();
                    }
            
                  }
                }
              }
            }
            With JRE6 I got this:
            Connected USB MIDI keyboard(MidiInDevice) to Microsoft MIDI Mapper(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to Microsoft GS Wavetable Synth(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to USB MIDI keyboard(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to Real Time Sequencer(RealTimeSequencer)
            Connected USB MIDI keyboard(MidiInDevice) to Java Sound Synthesizer(MixerSynth)
            And with JRE7 I got this:
            Connected USB MIDI keyboard(MidiInDevice) to Gervill(SoftSynthesizer)
            Connected USB MIDI keyboard(MidiInDevice) to Microsoft MIDI Mapper(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to Microsoft GS Wavetable Synth(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to USB MIDI keyboard(MidiOutDevice)
            Connected USB MIDI keyboard(MidiInDevice) to Real Time Sequencer(RealTimeSequencer)
            So it looks like the SoftSynthesizer in JRE7 replaced the Java MixerSynth in JRE6?

            Edited by: 974812 on 04-Dec-2012 05:40

            Edited by: 974812 on 04-Dec-2012 05:41

            Edited by: 974812 on Dec 4, 2012 3:02 PM
            • 3. Re: Midi Keyboard Delay
              1002736
              thanks for the code
              • 4. Re: Midi Keyboard Delay
                PhHein
                Stop posting to old threads, please.