【问题标题】:Lags while playing 2 sounds on the same time in timer在计时器中同时播放 2 个声音时滞后
【发布时间】:2013-09-25 21:23:41
【问题描述】:

我有一个小应用程序,它基本上设置了一个计时器并播放2个一组的声音一个接一个

我尝试了 2 个计时器,因为我希望两种声音每次都在同一时间开始。我给了应用程序 500 毫秒来设置两个计时器,然后才开始

    Calendar cal = Calendar.getInstance();
    Date start = new Date(cal.getTime().getTime() + 500);

    timerTask1 = new TimerTask() { //1st timer
      @Override
      public void run() {
          soundManager.playSound(1);
      }
    };
    timer1 = new Timer();
    timer1.schedule(timerTask1, start, 550);


    timerTask2 = new TimerTask() { //2nd timer
      @Override
      public void run() {
          soundManager.playSound(2);
      }
    };
    timer2 = new Timer();
    timer2.schedule(timerTask2, start, 550);
}

soundManager 是一个基于this tutorialSoundManager 对象。我所做的唯一更改是将可用流的数量从 20 个减少到 2 个,因为我同时只播放 2 个声音。

现在的问题。 在我的摩托罗拉 RAZR 或模拟器上播放速度不一样。该应用程序有时会变慢,使刹车时间比预期的要长。我不能让这种事发生。这里有什么问题?

我正在使用 OGG 格式的非常短的声音

编辑: 我做了一些研究。使用了2个方法。我正在测量声音发射之间的毫秒距离。刷新率为 500 毫秒。

  • 第一个方法是 TimerTask - 这是一个很大的失败。它从 300 毫秒开始,然后不断增长,并在一段时间(2 分钟)后稳定在 497 毫秒,如果这样开始就好了。
  • 第二个方法是在 AsyncTask 上进行 while 循环 - 它给了我 475 到 500ms 的输出,这比 TimerTask 好,但仍然不准确

最后没有一个方法播放得很顺利。总是有滞后

【问题讨论】:

  • 首先,TimerTask 不能保证是实时的,所以我可以想象在每个声音之间的 50 毫秒内有什么东西会打断你的进程。其次,似乎是先调用soundManager.playSound(1);,然后再调用soundManager.playSound(2);will play sequentially
  • 请注意,这两种声音都是从不同的线程中播放的,所以我希望它们在完全相同的时间开始,因为它们的开始时间相同。那么计时器任务有什么等价物呢?
  • 每个ogg文件的大小是多少

标签: android soundmanager2


【解决方案1】:

我知道这可能有点过多,但您可以尝试不同的 SoundPool 实现:

public class Sound {
    SoundPool soundPool;
    int soundID;

    public Sound(SoundPool soundPool, int soundID) {
        this.soundPool = soundPool;
        this.soundID = soundID;
    }

    public void play(float volume) {
        soundPool.play(soundID, volume, volume, 0, 0, 1);
    }

    public void dispose() {
        soundPool.unload(soundID);
    }
}

要使用它,您可以执行以下操作:

SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
AssetFileDescriptor assetFileDescriptor = activity.getAssets().openFd(fileName);
int soundID = soundPool.load(assetFileDescriptor, 0);

Sound sound = new Sound(soundPool, soundID);

然后播放:

sound.play(volume);

附:如果即使使用此代码问题仍然存在,请发表评论,我会尽快回复您。

【讨论】:

  • 我认为问题可能出在 SoundPool 以外的其他地方。根据这篇文章masterex.github.com/archive/2012/05/28/… TimerTask 不能保证我在正确的时间执行......
  • 然后尝试使用 AudioTrack。这可能是 SoundPool 不够高效的情况。在这种情况下,AudioTrack 应该是更好的选择:Android Developers Docs 实现可以类似于 Sound 类,只是这个需要更多信息。如果您在实施时遇到问题,我可以提供帮助。只需评论或 PM 我。
  • martinhoeller.net/2012/01/13/… 找到了这个不错的教程,按照那里的说明做了一切。仍然基本相同的滞后。我认为这不是声音管理器的情况,而是循环滞后。我不知道如何解决这个问题。我在问题中添加了注释
  • 也许你应该尝试使用 Java 7 的 Fork/Join:Java Docs
  • 最后尝试了您发布的方法,但输出是相同的。从 Java7 分叉/加入?我不认为 android 2.1 有那个...?
【解决方案2】:

您在使用 SoundPool 吗?它比 MediaPlayer 更快。将两种声音放在一起的最佳机会是在同一线程上播放它们。

【讨论】:

  • 是的,我正在使用 soundpool。我把它贴在链接下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2010-10-20
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多