AudioTrack - IllegalStateException: play () вызывается при неинициализированном AudioTrack - PullRequest
1 голос
/ 15 апреля 2019

У меня есть тема с AudioTrack, которую я вызываю по кнопке ВНИЗ, по кнопке ВВЕРХ, я хочу остановить аудио. Все идет нормально. В моем приложении есть активность A и активность B. Activity A - это меню, из которого я запускаю Activity B, которая является основной деятельностью, где я называю AudioTrack и так далее. Проблема в том, что все работает нормально, пока я не перехожу к занятию B в третий раз, тогда это произошло, когда я позвонил play.

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.

В 1-й и 2-й раз мне даже не нужно вызывать игру, просто войдите в Занятие B, но когда я хочу вызвать игру в третий раз, эта ошибка произошла. ПОЧЕМУ ???

Деятельность 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();

вот как я вызываю и / или останавливаю тему

setTuneFreq(double);

Я вызываю OnSenzorChanged (слушатель событий), потому что мне нужна частота на основе данных с гироскопа.

playTune();

Я вызываю OnTouchListener после ACTION_DOWN после нажатия кнопки и AudioTrack генерирует сигнал, пока она нажата (до ACTION_UP), затем я вызываю

stopTune();

Тема 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();
        }
    }

Мне нужно запустить эту тему даже после того, как я в третий раз открою Занятие B.

Что я делаю не так?

1 Ответ

0 голосов
/ 18 апреля 2019

Я думаю, что ваш аудио трек уничтожен сборщиком мусора.Поэтому я предлагаю вам повторно инициализировать siaudioTrack в самом начале метода run (), используя эту строку.

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