
// PanChanger.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* Třída PanChanger je vlákno pro úpravu polohy ve stereu, které
   pracuje se syntezátorem použitým při přehrávání MIDI-souborů
   v aplikaci PanMiDi.

   Upravuje nastavení polohy ve stereu každých CYCLE_PERIOD milisekund,
   dokud vyčerpaný čas nedosáhne známé délky skladby.

   Úpravu polohy ve stereu určuje pole panVals[]. Hodnota 0 
   znamená, že bude hrát pouze levý reproduktor. 127 znamená
   pouze pravý a 80 oba.

   Vlákno cyklicky prochází pole panVals[] dokud neskončí.
*/

public class PanChanger extends Thread
{
  // čas mezi jednotlivými změnami polohy sekvence ve stereu
  private static int CYCLE_PERIOD = 4000;  // v ms
  
  // hodnoty reprezentující polohy ve stereu 
  // (počet prvků v poli měl být dělitelem čísla CYCLE_PERIOD)
  private int[] panVals = {0, 127};
  // nebo můžeme vyzkoušet toto
  // private int[] panVals = {0, 16, 32, 48, 64, 80, 96, 112, 127, 
  //                          112, 96, 80, 64, 48, 32, 16};

  private PanMidi player;
  private int duration;  // trvání skladby v milisekundách


  public PanChanger(PanMidi p)
  {  super("PanChanger");  
     player = p;
  }


  public void startChanging(int d)
  /* PanMidi volá tuto metodu s parametrem délky 
     trvání MIDI-sekvence v milisekundách. */ 
  { duration = d;
    start();
  } // konec metody: startChanging()


  public void run()
  /* Upraví nastavení polohy ve stereu, trošku si pospi, poté vše opakuj, 
     dokud neuběhne čas odpovídající délce skladky.
  */
  { /* Získej původní nastavení polohy ve stereu. Jde jen o informaci,
       dále se nepoužívá. */
     int pan = player.getMaxPan();
     System.out.println("Max. hodnota pro polohu ve stereu: " + pan);
  
     int panValsIdx = 0;
     int timeCount = 0;
     int delayPeriod = (int) (CYCLE_PERIOD / panVals.length);

     System.out.print("Měním polohu ve stereu");
     while(timeCount < duration){ 
       try {
         if (player != null)
           player.setPan( panVals[panValsIdx] );
         Thread.sleep(delayPeriod);    // prodleva
       }
       catch(InterruptedException e) {}
       System.out.print(".");
       panValsIdx = (panValsIdx+1) % panVals.length;  // cyklicky procházíme pole
       timeCount += delayPeriod;
     } 
     System.out.println();
  } // konec metody: run()

}  // konec třídy: PanChanger
