AudioTrack: play () called by uninitialized AudioTrack

I am experimenting with the AudioTrack class. Basically, my application should generate sound when the user touches a specific object on the screen. I used this example as a guide.
My application seems to work as it should, but usually after touching the screen after 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) 

Sound class methods

 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 user view that uses my stream.

 @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 this is happening?

+8
android illegalstateexception audiotrack
source share
2 answers

I would think you need to call play() before you call write() .

But I also noticed that when you create many instances of AudioTrack , even if you think that you clear everything to write, sometimes play() does not work, and the track is not initialized.

You need to try ... to catch this IllegalStateException and avoid calling write() until play() throws an exception.

0
source share

Why did you comment out your stopPlaying () method?

You can create 32 AudioTracks. If you want more, you must call the release () method.

+1
source share

All Articles