понедельник, 22 ноября 2010 г.

Таймер со звуком

Один хороший друг придумал мне развлечение - написать ему таймер. Дело нехитрое, из переменных величин - количество итераций и продолжительность периода. При каждом прохождении выводить звук.
Реализовать звучание простого звука очень легко, он можно заставить приложение читать звук из файла или из интернета.
Кусочки исходника:
1. Обработчик команд. Запуск всего этого дела я доверил goCommand

   public void commandAction(Command c, Displayable s) {
      Timer t = new Timer();
      if (c == goCommand) {
      count = Integer.parseInt (countField.getString());
   duration = Long.parseLong (durationField.getString()) * 1000 ;
   // Таймер для очередного раунда
   MyTimerTask round = new MyTimerTask (this, 69, 100, 80);
   // Таймер для последнего раунда. отличается звуком и продолжительностью звучания
   MyTimerTask lastRound = new MyTimerTask (this, 70, 900, 100);
         // Задаем расписание для первого таймера
   t.schedule (round, 0, duration);
   // Задаем расписание для последнего раунда
   t.schedule (lastRound, duration*count);
   }
   // Выходим из приложения
   if (c == exitCommand) {
      t.cancel();
      notifyDestroyed();
      }
   }

2. Но чтобы все выполнялось как положено, то нужно выполнение команд из таймера выполнять в отдельных потоках. Поэтому:

class MyTimerTask
      extends TimerTask {
   private int tone, duration, volume;
   private timerMIDlet midlet;
   // Конструктор
   MyTimerTask (timerMIDlet midlet, int tone, int duration, int volume) {
      this.midlet = midlet;
      this.tone = tone;
   this.duration = duration;
   this.volume = volume;
   }
/** run() собственной персоной. проигрываем звук и уменьшаем количество раундов*/   
   public void run () {
      try {
      Manager.playTone (tone, duration, volume);
         //Выводим на экран количество оставшихся раундов
   midlet.mainForm.append ("Осталось "+String.valueOf(midlet.count));
   midlet.count--;
         if (midlet.count <= 0)
      this.cancel();
   }
   catch (Exception e)
      {System.err.println(e.toString());}
   }

}

Здесь я описал метод run(), который как раз будет запускаться отдельным потоком.

Звук воспроизводится командой Manager.playTone (tone, duration, volume);
Но как я писал выше, с этим можно и повеселится:

//ноты
   byte C4 = ToneControl.C4;; 
   byte D4 = (byte)(C4 + 2);
   byte E4 = (byte)(C4 + 4);
   byte G4 = (byte)(C4 + 7);
// последовательность
private byte[] enumRound = {
  ToneControl.VERSION, 1, 
  ToneControl.TEMPO, 120,
  ToneControl.BLOCK_START, 0,
  ToneControl.SET_VOLUME, 100,
  ToneControl.C4, 64, D4,8, E4,8,G4,8,D4,8,E4,8,G4,8,D4,8,C4,8,E4,8,G4,8,
  ToneControl.SILENCE, 4,
  ToneControl.BLOCK_END, 0,
  ToneControl.PLAY_BLOCK, 0   
   };
...
 Player p = Manager.createPlayer (Manager.TONE_DEVICE_LOCATOR);
 p.realize();
 ToneControl tc = (ToneControl)p.getControl("ToneControl");
 tc.setSequence (enumRound);
 VolumeControl vc = (VolumeControl)p.getControl("VolumeControl");
 vc.setLevel (100);
 p.prefetch();
 p.start();  

Или

   Player p = Manager.createPlayer ("http://server/somemusic.mp3");
   p.setLoopCount(5);
   p.start();

Комментариев нет:

Отправить комментарий