1

我遇到了一个问题,我想在静态模式下反复播放半秒AudioTrack,但声音断断续续。但是,我注意到在 aTransitionDrawable并行运行时声音非常清晰。

我的代码的简化骨架是:

thread = new Thread(new Runnable() {

  public void run() {
    createTransition();

    try {
      createAudioTrack();

      while (true) {
        if (audio) {
          playSoundClip();
        }

        if (display) {
          playScreenTransition();
        }

        Thread.sleep(getDelayBetweenBeats());
      }
    } catch (InterruptedException e) {
    } finally {
      resetScreenTransition();
      stopSoundClip();
    }
  }

  private void createAudioTrack() {
    short[] samples = generateSamples();
    track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLERATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, samples.length * 2, AudioTrack.MODE_STATIC);
    if (track.getState() != AudioTrack.STATE_UNINITIALIZED) {
      track.write(samples, 0, samples.length);
    }
  }

  private void playSoundClip() {
    if (track != null && track.getState() != AudioTrack.STATE_UNINITIALIZED) {
      track.stop();
      track.reloadStaticData();
      track.play();
    }
  }

  private void playScreenTransition() {
    view.post(new Runnable() {

      public void run() {
        view.setBackgroundDrawable(transition);
        transition.startTransition(DURATION);
      }

    });
  }

});
thread.start();

正如你所看到thread的,不是在 UI 线程上执行的,所以我假设它track面临着多线程问题。我不认为播放转换的 UI 线程会消耗整个 CPU,因为我的音频是并行播放的。似乎该活动以某种方式消耗了 CPU,并且没有执行任何其他操作。

我也尝试过使用view.post(new Runnable() {...});in playSoundClip(),但这并没有帮助。

我考虑将所有内容更改为AsyncTask,但恕我直言,这不会改变任何内容,因为它仍然是后台任务。由于我不需要使用声音更新 UI 元素,并且过渡仍然必须并行播放,我什至没有尝试过。

一个解决方案可能是总是让一些过渡并行运行(实际的或虚拟的),但这对我来说听起来很糟糕(双关语?)。

有谁知道另一种方法可以让我track始终保持清晰?


编辑:
在这个问题上做了更多工作并扩展了我的程序后,我注意到我必须使用上面列出的线程方法,因为那里的逻辑需要一些时间才能完成,我无法在 UI 上完成所有操作-线程了。目前,我在播放音频时播放了一个虚拟过渡,这对我来说仍然听起来很糟糕。因此,如果您仍然可以对该主题提供一些见解,欢迎您在此处发布/回答。

4

2 回答 2

2

您可能想看一下SoundPool,它可以让您将短音频样本静态加载到内存中一次,然后以低得多的延迟按需播放。您使用的方式AudioTrack是很好地使用重放音频而不重新加载,但对于如此短且经常重复的声音字节,它可能仍然有点重。

您也可以考虑根本不使用后台线程。从您的代码段中看起来您实际上只是将Thread用作计时器,并且您可能会通过使用 a在定时间隔上Handler发布您的结果来获得更好的性能Runnable(这也将允许您在主线程上调用您的音频/转换方法) 反而。

高温高压

于 2012-09-20T21:52:25.070 回答
0

我有更大的音频块,但我很幸运在我创建的服务中播放它们。

PS很好的双关语

于 2012-09-20T21:39:51.097 回答