如何正确使用线程/运行循环并使用SoundPool播放声音?

时间:2013-08-22 21:48:17

标签: java android multithreading audio soundpool

我正在构建一个以所选速度(bpm)播放音乐序列的应用。我目前正在使用一个线程来发出每个节拍的功能,然后使用SoundPool播放声音。但是,一次播放的声音越多,速度就越慢!

这是因为播放声音所需的时间会增加到playThread睡觉的时间吗?

soundPool.play应该在后台线程而不是UI线程吗?

我也会遇到同步问题,它会随机加速并减速,如果两个声音同时播放,它们并不总是在同一时间播放。 Android 2.3.4并没有那么糟糕,但出于某种原因,Android 4.2.2确实很糟糕。

实现稳定节奏和同步的最佳方式是什么?

这是我的主题:

public void playingThread()
{
    //Time interval in ms for thread sleep
    final long intervalInMs = (long) ((1 / (float) theBpm) * 60 * 250);

    Thread thread = new Thread() {
        @Override
        public void run() {
            while(playing == true) {
                beat();
                try {
                    Thread.sleep((long)(intervalInMs));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    thread.start();
}

然后它调用这个函数,它有很多额外的逻辑来计算播放和停止的声音等:

public void beat()
{
    currentBeat++;

    //Play click sound every four beats
    if(currentBeat % 4 == 0) {
        soundPool.play(clickSoundId, 0.5f, 0.5f, 1, 0, 1f);
    }

    //ADDITIONAL LOGIC TO DETERMINE WHICH SOUNDS TO PLAY...

    int streamId = soundPool.play(soundIds[i], 1f, 1f, 1, 0, 1f);
}

由于

2 个答案:

答案 0 :(得分:0)

不要使用Thread,也不要在主应用程序线程中休眠。使用处理程序。 Handler允许您安排将来发生的事情,而无需休眠主线程。请参阅我的回答here

答案 1 :(得分:0)

音乐总是对时间至关重要。 SoundPool不是为音乐所需的精确度而设计的。 SoundPool被设计成对输入有反应,在触发发生时产生声音,有时经常例如一个游戏。在生成音乐时,您通常会知道会发生什么样的声音,这样您就可以更好地安排它们。

我建议使用AudioTrack并直接写入音频缓冲区。这是完全控制声音何时相对于彼此播放的唯一方式。在延迟方面,您仍然受Android OS 硬件实施的支配,但至少每个节拍都会稳定!