简体   繁体   English

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

[英]AudioTrack - IllegalStateException: play() called on uninitialized AudioTrack

I have a Thread with AudioTrack that I call on button DOWN, on button UP i want to stop the audio. 我有一个带有AudioTrack的线程,我想在按钮DOWN上调用,在按钮UP上我想停止音频。 So far so good. 到现在为止还挺好。 My app have Activity A and Activity B. Activity A is some menu from where I start Activity B that is the Main Activity where I call this AudioTrack and so on. 我的应用程序具有活动A和活动B。活动A是我从中启动活动B的某个菜单,活动B是我称为AudioTrack的主要活动,依此类推。 Problem is, that everything is working fine until I go to Activity B for the 3rd time, then this happened when i call play. 问题是,一切正常,直到我第三次参加活动B,然后这才发生。

E/AudioTrack: AudioFlinger could not create track, status: -12
E/AudioTrack-JNI: Error -12 initializing AudioTrack
E/android.media.AudioTrack: Error code -20 when initializing AudioTrack.
java.lang.IllegalStateException: play() called on uninitialized AudioTrack.

For the 1st and 2nd time I don´t even have to call play, just enter the Activity B, but when I want to call play for the 3rd time, this error happened. 对于第1次和第2次,我什至不必调用play,只需输入活动B,但是当我想第3次调用play时,就会发生此错误。 WHY??? 为什么???

Activity B looks like that 活动B看起来像

Activity B playTune(){
    if(tuneThread == null){
        tuneThread = new startSI();
        //    tuneThread.setTuneFreq(tuneFreq);
        tuneThread.start();
    }
    return this;
}

void setTuneFreq(double tuneFreq) {
    this.tuneFreq = tuneFreq;
    if(tuneThread != null){
        tuneThread.setTuneFreq(tuneFreq);
    }
}

void stopTune(){
    if(tuneThread != null){
        tuneThread.stopTune();
        tuneThread = null;
    }
}

protected void onPause() {
    stopTune();
    super.onPause();
}

protected void onStop() {
    stopTune();
    super.onStop();

this is how I call and/or stop thread 这就是我调用和/或停止线程的方式

setTuneFreq(double);

I call in OnSenzorChanged (event Listener) because I need frequency based on data from gyroscope. 我之所以调用OnSenzorChanged(事件监听器),是因为我需要基于陀螺仪数据的频率。

playTune();

I call in OnTouchListener after ACTION_DOWN after button is pressed and AudioTrack generate signal as long as it is pressed (until ACTION_UP), then I call 按下按钮后,在ACTION_DOWN之后我在OnTouchListener中调用,只要按下它,AudioTrack就会生成信号(直到ACTION_UP),然后我调用

stopTune();

AudioTrack Thread looks like this AudioTrack线程看起来像这样

public class startSI extends Thread {

    private boolean isRunning;
    private double tuneFreqSI;


    private int sr = 44100;
    private int sibuffsize = AudioTrack.getMinBufferSize(sr,
            AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    private AudioTrack siaudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sr, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, sibuffsize,
            AudioTrack.MODE_STREAM);


    @Override
    public void run() {

        super.run();
        isRunning = true;


        short samples[] = new short[sibuffsize];
        int amp = 32767;
        double twopi = 8. * Math.atan(1.);
        double ph = 0.0;

        try {

        siaudioTrack.play();

        } catch(IllegalStateException e) {
            System.out.println("error play "+e);   
        }

        while (isRunning) {

            double fr = tuneFreqSI;
            double fLFO = frLFO;
            for (int i = 0; i < sibuffsize; i++) {
                samples[i] = (short) (amp * Math.sin(ph));
                ph += twopi * fr / sr;               
            }
            siaudioTrack.write(samples, 0, sibuffsize);       

        }
        try {
        siaudioTrack.stop();
        siaudioTrack.release();

        }catch(IllegalStateException e) {
            System.out.println("error stop "+e);
        }

    }

    public void setTuneFreq(double tuneFreq, double frLFO, double ampLFO) {

        this.tuneFreqSI = tuneFreq;
        this.frLFO = frLFO;
        this.ampLFO = ampLFO;
    }


    public void stopTune() {
        isRunning = false;

        try {
            this.join();
            this.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

I need to start this thread even after I open Activity B for the 3rd time. 即使我第三次打开活动B,也需要启动此线程。

What Am I doing wrong? 我究竟做错了什么?

I think, that your Audio Track is destroyed by Garbage Collector in meantime. 我认为您的音轨同时已被垃圾收集器破坏。 So I suggest you to reinitialize the siaudioTrack at the very begginning of run() method using this line. 因此,我建议您使用此行在run()方法开始时重新初始化siaudioTrack。

this.siaudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, sibuffsize, AudioTrack.MODE_STREAM);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM