【问题标题】:Play sound precisely every one second每隔一秒精确播放一次声音
【发布时间】:2016-01-05 16:40:37
【问题描述】:

我正在学习为 Android 编写代码,但我遇到了问题……也许是性能问题? 我想每秒播放很短的声音。我创建了一个 CountDownTimer(滴答间隔 20 毫秒,非常准确),并在 onTick 中播放它。但是声音不是在一秒钟后播放的,我能听到 - 这就是问题所在......

我的代码片段:

private class ExerciseCountDownTimer extends CountDownTimer
{
...
public void onTick(long millisUntilFinished)
{
    ...
    if(/*this is a next second not just a tick*/)
        playSound(R.raw.quick_rest, true);
}
}

private void playSound(int resId, boolean releaseAfter)
{
    if (currentMediaPlayerRes != resId || mediaPlayer == null)
    {
        if (mediaPlayer != null)
        {
            if (mediaPlayer.isPlaying())
                mediaPlayer.stop();
            mediaPlayer.reset();
            mediaPlayer.release();
        }
        currentMediaPlayerRes = resId;
        mediaPlayer = MediaPlayer.create(this, resId);
        if (releaseAfter)
        {
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
            {
                @Override
                public void onCompletion(MediaPlayer mp)
                {
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
            });
        }
    }

    mediaPlayer.start();
}

这样的计数器有可能吗?

【问题讨论】:

标签: android performance audio


【解决方案1】:

使用此代码播放一首音乐

 MediaPlayer AlarmMusic;
 AlarmMusic = MediaPlayer.create(G.context, R.raw.music1);
 AlarmMusic.setLooping(false);
 AlarmMusic.start();

这对我有用!

【讨论】:

  • 其实我可以多次播放一个声音。问题是声音不是每秒都精确播放。听说有时早有时晚。
【解决方案2】:

由于在 Java/Android 中缺乏实时保证,使用一个线程提示另一个线程可能总是会有一些不准确。

我能想到两种可能对你有用的方法:

(1) 如果您使用 Java 支持的标准“CD 质量”格式,则使声音文件的长度正好为 1 秒,例如 44100 帧,每秒 44100 帧。声音文件可能可以用 Audacity 编辑到精确的帧长度。然后,使用循环播放。

(2) 为流式音频打开一行。我不记得确切的 Android 支持的命令是什么,但我知道它存在。使用它,在发送静音(值为 0 的字节)时计算经过的帧数。当您到达第 44100 帧时,开始输入您希望听到的 PCM 数据。完成后,返回输入 0,直到下一个 44100 帧到达。永远不要停止这条线——让它在自己的线程中运行,可能具有高优先级。通常可以给音频高优先级(只要您在线路上没有做任何其他事情),因为音频大部分时间都处于“阻塞”状态,在此期间它会让步给其他线路。

java-gaming.org 上的一位同事制作了一个节拍器,并让它在 Android 上运行。我敢打赌,如果您在该网站上搜索“节拍器”,他的帖子会弹出并提供一些有用的信息。他基本上使用了我上面描述的第二种方法。

【讨论】:

  • 嗯,第 1 点很好,很简单。我会试试这个,并在检查这是否可行后将您的帖子标记为答案。如果不是,那么可能是第 2 点,但听起来有点复杂。
  • 循环没有帮助。下一个循环之间花了一些时间,我认为它在精确的空间中,但我不想属于这个,因为可能这个空间在不同的设备上可能会有所不同......如果我有时间,我会尝试第二个选项。跨度>
  • 您使用什么命令进行循环?我想看看它的api。我想到了第三种可能性:获取您制作的文件(假设它的帧数完全正确)并将其作为 Android 流式音频命令的源数据:每次到达最后一个字节时,重新启动。然后,您不必计算经过的帧数或管理何时发送 0 而不是文件本身。
猜你喜欢
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多