首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioTrack:在未初始化的AudioTrack上调用play()

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

Stack Overflow用户
提问于 2012-07-03 02:13:12
回答 2查看 10.8K关注 0票数 9

我正在试验AudioTrack类。基本上,我的应用程序必须在用户触摸屏幕上的特定对象时发出声音。我已经使用了this example作为指南。

我的应用程序似乎正常工作,但通常在触摸屏幕大约一分钟后,它会崩溃:

代码语言:javascript
复制
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)

来自生成声音的类的方法

代码语言:javascript
复制
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);
            }
        }
    }

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

代码语言:javascript
复制
@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;
    }

你知道为什么会发生这种情况吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-12 10:17:01

我认为在调用write()之前需要先调用play()

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

您将希望try...catch此IllegalStateException,并避免调用write(),直到play()正常工作而不抛出异常。

票数 1
EN

Stack Overflow用户

发布于 2013-06-15 17:47:23

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

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11298949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档