java audiotrack,AudioTrack:玩()呼吁未初始化AudioTrack

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 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?

解决方案

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

But I've also noticed that when you create lots of AudioTrack instances even if you think you're cleaning everything up write, sometimes a play() fails to work, and the track is uninitialized.

You will want to try...catch this IllegalStateException, and avoiding calling write() until play() works without throwing an exception.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值