每N毫秒播放一次声音

我正在开发一个节拍器应用程序。 用户可以在运行时selectbpm,我的应用程序将相应地播放“tick”声音。 “嘀嗒”是一个单一的节拍器“射击”(MP3)。 我试着用Handler和MediaPlayer来实现它,但是节拍器并不精确。 所以我想改变整个方法:当用户select一个新的bpm值时,我会每N毫秒重复一次tick音来合成一个新的声音,然后循环这个运行时创build的声音。 这是一个有效的select? 如何在Android中实现?

Solutions Collecting From Web of "每N毫秒播放一次声音"

循环合成声音的替代方法似乎是现在的最佳select。 在Google I / O 2013上有一个关于audio的很棒的会议,名为“ 高性能audio” ( High Performance Audio) ,我当然会build议您观察一下这个系统是如何工作的,以及开发人员在处理audio延迟时遇到的问题。 在video的17点左右,有一个显示抖动与callback的图表。 在不存在的完美世界里(哦,真的吗?),对于所有预定的audiocallback,抖动将是零。 但情况并非如此,因为图表中的数据是使用未指定的ICS器件制作的,而且情况肯定比这更糟糕。

所以,作为一个节拍器是一个精确的工具,这些抖动不好,预定的播放方式应该放在一边。 我甚至使用AudioTrack制作了一个合理可靠的节拍器。

希望它有助于^^

您可以尝试使用计时器上定时执行固定速率的TimerTask 。

Timer和TimerTask都是Android SDK(和Java SE)的一部分。 由于前一个事件的执行时间,执行不会延迟。

 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. 

您可以在需要更改BPM时取消TimerTask。

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

另一种可能符合你的要求(从你的意见)的可能性是旋转一个线程,并检查System.nanoTime()和睡觉增量,但旋转时,你近距离醒来。

 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; } } 

当这个播放声音被调用

 mSoundManager.playSound(1); 

Android等待,直到这个通话完成,然后你打电话

 mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200); 

但是,如果您反转这些电话,您可能会发现时间更准确。

 mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200); mSoundManager.playSound(1); 

你不能指望你的声音播放完全相同的时间,所以告诉处理器首先发布是好一点。 然而,仍然不理想。