Play a sound every N milliseconds

前端 未结 3 1411
北荒
北荒 2021-01-04 09:19

I\'m developing a metronome application. The user can select at runtime the bpm, and my app will play the \"tick\" sound accordingly. The \"tick\" is a single metronome \"sh

3条回答
  •  旧时难觅i
    2021-01-04 09:40

    You could try to use a TimerTask scheduled for fixed-rate execution on a Timer.

    Timer and TimerTask are both part of the Android SDK (and Java SE). The executions do not delay because of execution time of the previous event.

    Timer timer = new Timer("MetronomeTimer", true);
    TimerTask tone = new TimerTask(){
         @Override
         public void run(){
             //Play sound
         }
    };
    timer.scheduleAtFixedRate(tone, 500, 500); //120 BPM. Executes every 500 ms.
    

    You can then cancel the TimerTask when you need to change the BPM.

    tone.cancel();
    tone = new TimerTask(){...}
    timer.scheduleAtFixedRate(tone, 1000, 1000); //60 BPM. Executes every 1000 ms.
    

    Another possibility that may meet your requirements (from your comments) is spinning a thread and checking System.nanoTime() and sleeping in increments but spinning when you get close to wake up.

    long delayNanos = 500000000;
    long wakeup = System.nanoTime() + delayNanos; //Half second from right now
    long now;
    
    while(!done){
         now = System.nanoTime();
    
         //If we are less than 50 milliseconds from wake up. Spin away. 
         if(now <= wakeup - 50000000){
              //Sleep in very small increments, so we don't spin unrestricted.
    
              Thread.sleep(10); 
         }
         if(now >= wakeup){
               //Play sound
               wakeup += delayNanos;
         }
    }
    

提交回复
热议问题