1

我正在构建一个应用程序,它以选定的速度 (bpm) 播放音乐序列。我目前正在使用线程在每个节拍中触发一个函数,然后使用 SoundPool 播放声音。但是,同时播放的声音越多,速度就越慢!

这是因为播放声音所花费的时间被添加到了正在播放线程睡眠的时间上吗?

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

谢谢

4

2 回答 2

0

不要使用线程,也不要让主应用程序线程休眠。使用处理程序。处理程序允许您在不休眠主线程的情况下安排将来发生的事情。在这里查看我的答案

于 2013-10-17T15:53:09.873 回答
0

音乐总是时间紧迫的。SoundPool 并非专为音乐所要求的精确度而设计。SoundPool 被设计为对输入做出反应,在触发发生时产生声音,有时通常是游戏。经常生成音乐时,您知道什么时候会发生什么声音,这样您就可以更好地安排它们。

我建议使用 AudioTrack 并直接写入音频缓冲区。这是完全控制声音何时播放的唯一方法。在延迟方面,您仍然受制于 Android 操作系统硬件实现,但至少每个节拍都是稳定的!

于 2015-02-02T13:47:28.940 回答