title: AudioTrack: play() called on uninitialized AudioTrack
body: <p>I'm experimenting with AudioTrack class. Basically, my app has to generate a sound when the user touches a specific object on screen. I've used <a href="http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html">this example</a> as a guide. <br>
  My app seems to work as it should but usually after touching the screen for about a minute it crashes: <br></p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Methods from class that generates sounds <br></p>
  
  <pre><code>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);
              }
          }
      }
  </code></pre>
  
  <p>This is a method from a custom view my thread is used <br></p>
  
  <pre><code>@Override
      public boolean onTouchEvent(final MotionEvent ev) {
          int currentXPosition = (int) ev.getX();
          int currentYPosition = (int) ev.getY();
  
          if(ev.getX() &lt; smBitmap.getWidth())
              if(ev.getY() &lt; smBitmap.getHeight()){
                  tempCol = smBitmap.getPixel(currentXPosition, currentYPosition);
              }
  
          final int action = ev.getAction();
  
          switch (action &amp; 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;
      }
  </code></pre>
  
  <p>Any ideas why is this happening?</p>