2

I have a Thread with AudioTrack that I call on button DOWN, on button UP i want to stop the audio. 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. Problem is, that everything is working fine until I go to Activity B for the 3rd time, then this happened when i call 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.

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

Activity B looks like that

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.

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

stopTune();

AudioTrack Thread looks like this

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.

What Am I doing wrong?

Fábio Nascimento
  • 2,644
  • 1
  • 21
  • 27
  • According to [here](https://stackoverflow.com/a/43073175/6759241), -12 is "out of memory". Are you getting any `error stops`? You should make the `.release()` call unconditional, even if the `stop()` throws. Although, I'm not sure that's the root cause of your problem. – greeble31 Apr 15 '19 at 15:58
  • Same problem, when I call ´release()´ unconditional, nothing happens, same error. Even when I set at the end buffer to 0 and AudioTrack to null, same error – Filip Barák Apr 17 '19 at 10:09
  • This looks like it should work. What device is this on? Also, it would be helpful if you could post a log dump, including all calls to `playTune()`/`stopTune()`, and/or more code. – greeble31 Apr 17 '19 at 13:24
  • Well it seems to be problem with my testing phone (Xperia Z5 Compact), because on my Xperia XZ1 Compact, or Xperia XZ1, Honor9, LG g8... it seems to be ok and working just fine. Weird error.... – Filip Barák Apr 21 '19 at 17:11

1 Answers1

-1

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.

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