Java String parsing and playback through MIDI Synthesizer error

148 views Asked by At

I'm trying to implement a morse playback mechanism in Java. I had it working fine with a String, but in order to implement a stop function, I am trying to have it work with a single char, which would be delivered one at a time from the driver.

However, the program seems to somewhat randomly cease playback. For instance:

"Hello": ... . .-.. .-.. ---

Goes silent just before the "---"

"hhhh": .... .... .... ....

Goes silent after the first dot of the fourth h.

"ooooo" : --- --- --- --- ---

Goes silent after the fourth o.

Driver:

Runnable r = new Runnable() {
  public void run() {
      Morse.play(returnval);
      /*
      char[] c = returnval.toCharArray();
      for (char v : c){
        String s = "";
        s += v;
        System.out.print(s);
        Morse.play(s);
      }
        */
  }
};

new Thread(r).start();

Playback method:

public static void play(String morse){
    char[] notes = morse.toCharArray();
    int unit = 100;
    int mult = 0;

    try {
        Synthesizer synthesizer = MidiSystem.getSynthesizer();
        synthesizer.open();

        MidiChannel channel = synthesizer.getChannels()[0];
        channel.programChange(0, 80);
        for (char note : notes) {
            switch (note){
            case '.':
                mult = 1;
                break;
            case '-':
                mult = 3;
                break;
            case ' ':
                mult = -3;
                break;
            default:
                mult = 0;
                break;
            }
            try{
                if (mult > 0){
                    channel.noteOn(60, 30);
                    Thread.sleep(mult*unit);
                }

                else {
                    Thread.sleep(mult*-1*unit);
                }

                channel.allNotesOff();
                Thread.sleep(100);

            } catch (InterruptedException e) {
                e.printStackTrace();
            } 

        }
    } catch (MidiUnavailableException e) {
        e.printStackTrace();
    }
}
1

There are 1 answers

0
Christian Hujer On BEST ANSWER

Actually the code looks all okay and should work. However, there can be glitches due to Synthesizer being too slow and the selected instrument having a decay. I could improve the results on my end by introducing an additional delay of 1000ms at the end after playing the Morse code sequence, so that the Thread would not stop yet and the Midi resources would not be closed / reclaimed too early. The required delay might depend on the system and the chosen instrument.