AudioTrack:play() 在未初始化的 AudioTrack 上调用



我正在试验AudioTrack类。 基本上,当用户触摸屏幕上的特定对象时,我的应用必须生成声音。我用这个例子作为指导。
我的应用程序似乎可以正常工作,但通常在触摸屏幕大约一分钟后它会崩溃:

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)

类中生成声音
的方法

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

这是我的线程使用的
自定义视图中的方法

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

任何想法为什么会这样?

为什么你注释掉了你的 stopPlaying() 方法?

您只能创建 32 个音轨。如果你想要更多,你应该调用 release() 方法。

我认为您需要在致电write()之前致电play()

但我也注意到,当你创建大量AudioTrack实例时,即使你认为你正在清理所有内容,有时play()无法正常工作,并且轨道未初始化。

你会想尝试...捕获此IllegalStateException,并避免调用write()直到play()工作而不会引发异常。

对于我的情况,我不知何故打电话给 -

audioTrack.release(); 

.play()打电话之前。我删除了它,然后它按预期工作。

最新更新