2012-01-23 2 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! 

이는 소스 코드입니다. 나는 멈춤을 호출하고 다음 "실행"실행을 위해 데이터를 다시로드하도록 노력하고있다.

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

사람이 처리하는 방법을 알고 있나요 : 우리는 안드로이드 소스 코드를 열면

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

} 

, 그것은 많은 설명하지 않는 이유는 무엇입니까?

답변

4

한 번 비슷한 문제가있었습니다. 당신이 AudioTrack을 작성하고 그것을 play()stop()를 호출하면 동일한 스레드에서 발생해야한다는 것을 확인해야 물건을 하나 개 이상의 스레드에서 실행이 일어날 경우

은 간단히했습니다.

그러나 해당 스레드에서 오디오 샘플을 만들어야한다는 의미는 아닙니다. 정적 오디오 데이터 (AudioTrack.MODE_STATIC)를 사용하는 경우 다른 곳에서 미리로드하거나 생성 한 다음 앱 수명 기간 동안 여러 번 사용할 수도 있습니다.