package sound;

/*
 * Open Source Software by http://www.Docjava.com
 * programmer: D. Lyon
 * e-mail: lyon@docjava.com
 * Date: Apr 29, 2002
 * Time: 12:35:09 PM
 */

import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;

public class Utils {
  private static MidiChannel channels[] = null;
  private static Synthesizer synth = null;

  public static void play(int ia[], int vel, int dur) {
    for (int i = 0; i < ia.length; i++)
      play(ia[i], vel, dur);
  }

  public static void playThread(
      final int ia[],
      final int vel,
      final int dur) {
    Runnable r = new Runnable() {
      public void run() {
        for (int i = 0; i < ia.length; i++)
          play(ia[i], vel, dur);

      }
    };
    Thread t = new Thread(r);
    t.start();
  }

  public static void play(int ia[], int dur) {
    for (int i = 0; i < ia.length; i++)
      play(ia[i], 127, dur);
  }

  public static int[] transpose(int ia[], int bias) {
    int ans[] = new int[ia.length];
    for (int i = 0; i < ans.length; i++)
      ans[i] = ia[i] + bias;
    return ans;
  }

  public static void print(int ia[]) {
    for (int i = 0; i < ia.length; i++)
      System.out.println(ia[i]);
  }

  public static void play(int nn) {
    play(nn, 127, 20);
  }

  public static void play(int nn, int dur) {
    play(nn, 127, dur);
  }

  public static void play(int nn, int vel, int dur) {
    play(getSynthesizer(), nn, vel, dur);
  }

  protected static void play(Synthesizer synth, int nNoteNumber,
                             int nVelocity, int nDuration) {
    noteOn(nNoteNumber, nVelocity);
    if (nDuration < 0) return;
    sleep(nDuration);
    noteOff(nNoteNumber);
  }

  private static void noteOff(int nNoteNumber) {
    channels[0].noteOff(nNoteNumber);
  }

  private static void noteOn(int nNoteNumber, int nVelocity) {
    channels[0].noteOn(nNoteNumber, nVelocity);
  }

  private static void sleep(int nDuration) {
    try {
      Thread.sleep(nDuration);
    } catch (InterruptedException e) {
    }
  }


  protected static Synthesizer getSynthesizer() {
    Synthesizer synth = initSynth();
    openSynth(synth);
    channels = initChannel(synth);
    return synth;
  }

  private static Synthesizer initSynth() {
    if (synth != null) return synth;
    try {
      synth = MidiSystem.getSynthesizer();
    } catch (MidiUnavailableException e) {
    }
    return synth;
  }

  private static void openSynth(Synthesizer synth) {
    try {
      synth.open();
    } catch (MidiUnavailableException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  private static MidiChannel[] initChannel(Synthesizer synth) {
    MidiChannel[] channels = synth.getChannels();
    return channels;
  }

}