2012-07-02 6 views
8

Sto sperimentando con la classe AudioTrack. Fondamentalmente, la mia app deve generare un suono quando l'utente tocca uno specifico oggetto sullo schermo. Ho usato this example come guida.
mia app sembra funzionare come dovrebbe, ma di solito dopo aver toccato lo schermo per circa un minuto si blocca:
AudioTrack: play() chiamato su AudioTrack non inizializzato

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) 

I metodi di classe che genera suoni

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

Questo è un metodo da una visualizzazione personalizzata mio thread viene utilizzato

@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; 
    } 

Tutte le idee w sta succedendo?

+0

'// sThread.initAudioTrack();' Decomprimi questo –

+0

Ho detto un commento, non rimuovere –

+0

Scusa, intendevo dire un commento. – droid8421

risposta

0

Vorrei pensare che è necessario chiamare play() prima di chiamare write().

ma ho anche notato che quando si crea un sacco di AudioTrack casi, anche se si pensa che stai pulizia tutto up di scrittura, a volte un play() non funziona, e la pista non è inizializzato.

Si vorrà provare ... prendere questo IllegalStateException ed evitando di chiamare write() fino a play() funziona senza generare un'eccezione.

1

Perché hai commentato il tuo metodo stopPlaying()?

È possibile creare solo 32 traccia audio. Se vuoi di più devi chiamare il metodo release().