2012-07-02 2 views
8

Я экспериментирую с классом AudioTrack. В основном, мое приложение должно генерировать звук, когда пользователь касается конкретного объекта на экране. Я использовал this example в качестве руководства.
Мое приложение, кажется, работает, как и должно быть, но обычно после прикосновения к экрану в течение минуты он выходит из строя:
AudioTrack: play() вызывается неинициализированным AudioTrack

07-02 20:40:53.459: E/AndroidRuntime(11973): FATAL EXCEPTION: Thread-10 
07-02 20:40:53.459: E/AndroidRuntime(11973): java.lang.IllegalStateException: play() called on uninitialized AudioTrack. 
07-02 20:40:53.459: E/AndroidRuntime(11973): at android.media.AudioTrack.play(AudioTrack.java:824) 
07-02 20:40:53.459: E/AndroidRuntime(11973): at com.mysounds_experimental.SoundThread.playSound(SoundThread.java:108) 
07-02 20:40:53.459: E/AndroidRuntime(11973): at com.mysounds_experimental.SoundThread.run(SoundThread.java:69) 

методы из класса, который генерирует звуки

public void initAudioTrack() { 
     int bufferSize = AudioTrack.getMinBufferSize(sampleRate 
       , AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); 

     audioTrack = new AudioTrack(
       AudioManager.STREAM_MUSIC 
       , sampleRate 
       , AudioFormat.CHANNEL_CONFIGURATION_MONO 
       , AudioFormat.ENCODING_PCM_16BIT 
       , bufferSize 
       , AudioTrack.MODE_STREAM); 
    } 

    private void playSound(){ 
      audioTrack.write(generatedSnd, 0, numSamples); 
      audioTrack.play(); 
     } 

public void stopPlaying() { 
    audioTrack.flush(); 
    audioTrack.stop(); 
    audioTrack.release(); 
} 

@Override 
    public void run() { 
     while (mRun) { 
      try{ 
       Thread.sleep(200); 
       while(soundCycle){ 
        if(freqOfTone != -1f) { 
         generateTone(); 
         playSound(); 
         Thread.sleep(200); 
        } 
       } 
      } catch(InterruptedException e){ 
       //    soundCycle = false; 
       //    soundPool.stop(BEEP); 
      } 
     } 
    } 

Это метод из обычай смотреть мою нить используется

@Override 
    public boolean onTouchEvent(final MotionEvent ev) { 
     int currentXPosition = (int) ev.getX(); 
     int currentYPosition = (int) ev.getY(); 

     if(ev.getX() < smBitmap.getWidth()) 
      if(ev.getY() < smBitmap.getHeight()){ 
       tempCol = smBitmap.getPixel(currentXPosition, currentYPosition); 
      } 

     final int action = ev.getAction(); 

     switch (action & MotionEvent.ACTION_MASK) { 

     case MotionEvent.ACTION_DOWN: { 

      sThread.freqOfTone = getFreqPreset(tempCol); 
      if(col != tempCol){ 
//    sThread.initAudioTrack(); 
       sThread.interrupt(); 
       if(shouldInit) { 
        shouldInit = false; 
        sThread.initAudioTrack(); 
       } 
       sThread.soundCycle = true; 
       col = tempCol; 
       invalidate(); 
      } 
      break; 
     } 

     case MotionEvent.ACTION_MOVE: { 
      sThread.freqOfTone = getFreqPreset(tempCol); 

      if (tempCol == -1 || tempCol == 0) { 
       sThread.soundCycle = false; 
       shouldInit = true; 
//    sThread.stopPlaying(); 
       sThread.interrupt(); 
       invalidate(); 
      } else { 
       if(col != tempCol){ 
        sThread.interrupt(); 
        col = tempCol; 
        invalidate(); 
       }else { 
        sThread.soundCycle = true; 
        col = tempCol; 
        invalidate(); 
       } 
      } 
      break; 
     }// case ACTION_MOVE 

     case MotionEvent.ACTION_UP: { 
      sThread.soundCycle = false; 
      shouldInit = true; 
//   sThread.stopPlaying(); 
      sThread.interrupt(); 
      col = -1; 
      mActivePointerId = INVALID_POINTER_ID; 
      break; 
     }// case ACTION_UP 

     } 

     return true; 
    } 

Любые идеи ш Это происходит?

+0

'// sThread.initAudioTrack();' Uncomment this –

+0

Я сказал, что раскол, а не удалить –

+0

Извините, я хотел сказать раскоммент. – droid8421

ответ

0

Я думаю, что вам нужно позвонить в play(), прежде чем звонить по телефону write().

Но я также заметил, что когда вы создаете много экземпляров AudioTrack, даже если вы считаете, что очищаете все, напишите, иногда play() не работает, а трек неинициализирован.

Вы хотите попробовать ... поймать это IllegalStateException и избежать звонка write() до play() работает без исключения.

1

Почему вы прокомментировали свой метод stopPlaying()?

Вы можете создавать 32 AudioTracks. Если вы хотите больше, вы должны вызвать метод release().