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 [this example](http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html) as a guide.   

My app seems to work as it should but usually after touching the screen for about a minute it crashes:   

```
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)

```

Methods from class that generates sounds   

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

```

This is a method from a custom view my thread is used   

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

```

Any ideas why is this happening?