2012-01-23 28 views
1

AudioTrackを静的モードで使用して、同じ信号を繰り返し再生します。AudioTrack:スレッドから呼び出される

は、私はここでの例に従っていると、時にはそれが完璧に動作しますが、時にはそれがこのエラーをスローし、それから音が出ません:

AudioTrack: start called from a thread 
01-23 15:26:16.902: W/libutils.threads(1133): Thread (this=0x3973b8): don't call waitForExit() from this Thread object's thread. It's a guaranteed deadlock! 

これは、ソースコードです。私は、次の "再生"実行のためにデータを停止してリロードするようにしています。

 public class SoundPlayer { 
    // originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html 
     private int numSamples; 
     private double sample[]; 
     private byte generatedSnd[]; 
     private AudioTrack audioTrack; 

     public SoundPlayer(float duration, int sampleRate, double freqOfTone) { 
      super(); 
      this.numSamples = (int) (duration * sampleRate); 
      this.sample = new double[numSamples]; 
      this.generatedSnd = new byte[2 * numSamples]; 
      // fill out the array 
      for (int i = 0; i < numSamples; ++i) { 
       sample[i] = Math.sin(2 * Math.PI * i/(sampleRate/freqOfTone)); 
      } 
      // convert to 16 bit pcm sound array 
      // assumes the sample buffer is normalised. 
      int idx = 0; 
      for (final double dVal : sample) { 
       // scale to maximum amplitude 
       final short val = (short) ((dVal * 32767)); 
       // in 16 bit wav PCM, first byte is the low order byte 
       generatedSnd[idx++] = (byte) (val & 0x00ff); 
       generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 

      } 
      audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
        sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
        AudioFormat.ENCODING_PCM_16BIT, numSamples, 
        AudioTrack.MODE_STATIC); 
      audioTrack.write(generatedSnd, 0, generatedSnd.length); 
     } 

     public void playSound() { 
      if (audioTrack.getPlayState() == (AudioTrack.PLAYSTATE_PLAYING | AudioTrack.PLAYSTATE_PAUSED)) { 
       audioTrack.stop(); 
       audioTrack.reloadStaticData(); 
      } 
      Log.i("Audio", "playState: " + audioTrack.getPlayState()); 
      audioTrack.play(); 
      audioTrack.stop(); 
      audioTrack.reloadStaticData(); 
     } 

} 

我々はアンドロイドのソースコードを開くと、それは多くのことを説明していません:

void AudioTrack::start() 
{ 
sp<AudioTrackThread> t = mAudioTrackThread; 

LOGV("start"); 
if (t != 0) { 
    if (t->exitPending()) { 
     if (t->requestExitAndWait() == WOULD_BLOCK) { 
      LOGE("AudioTrack::start called from thread"); 
      return; 
     } 
    } 
    t->mLock.lock(); 
} 

誰もがこれを処理する方法を知っていますか?

答えて

4

私は一度同様の問題がありました。あなたはAudioTrackを作成し、それにplay()stop()を呼び出すと同じスレッドで発生しなければならないことを確認する必要があり、複数のスレッドで実行されているものを持って起こる場合

は単に、置きます。

ただし、そのスレッドでオーディオサンプルを作成する必要はありません。静的なオーディオデータ(AudioTrack.MODE_STATIC)を使用している場合は、別の場所にあらかじめ読み込んだり、生成したりして、アプリの生涯にわたって複数回使用することもできます。

関連する問題