Unable to retrieve AudioTrack pointer for write()
Asked Answered
D

1

7

I am trying to implement AudioTrack to retrieve audio in my android device for incoming call from IAX but facing exception after some while .

private void writeBuff(short[] buf) {

    try {

        if (this.track == null) {
            Log.w("IAX2Audio", "write() without an AudioTrack");
            return;
        }

        int written = 0;
        while (written < buf.length) {


            if (this.track != null) {
                int res;

                res = this.track.write(buf, written, buf.length - written);      
                switch (res) {
                case AudioTrack.ERROR_INVALID_OPERATION:
                    Log.e("IAX2Audio", "Invalid write()");
                    return;
                case AudioTrack.ERROR_BAD_VALUE:
                    Log.e("IAX2Audio", "Bad arguments to write()");
                    return;
                }

                written += res;
            }

        }

    } catch (Exception e) {
        e.printStackTrace();
    }

}

And the exception goes here

 04-27 18:26:15.865: W/System.err(12681): java.lang.IllegalStateException: Unable to retrieve AudioTrack pointer for write()
04-27 18:26:15.890: W/System.err(12681):    at android.media.AudioTrack.native_write_short(Native Method)
04-27 18:26:15.895: W/System.err(12681):    at android.media.AudioTrack.write(AudioTrack.java:1023)
04-27 18:26:15.900: W/System.err(12681):    at org.androvoip.iax2.AndroidAudioInterface.writeBuff(AndroidAudioInterface.java:322)
04-27 18:26:15.900: W/System.err(12681):    at org.androvoip.iax2.AndroidAudioInterface.playbackTime(AndroidAudioInterface.java:350)
04-27 18:26:15.905: W/System.err(12681):    at org.androvoip.iax2.AndroidAudioInterface.playTick(AndroidAudioInterface.java:413)
04-27 18:26:15.905: W/System.err(12681):    at org.androvoip.iax2.AndroidAudioInterface.access$2(AndroidAudioInterface.java:406)
04-27 18:26:15.910: W/System.err(12681):    at org.androvoip.iax2.AndroidAudioInterface$3.run(AndroidAudioInterface.java:560)
04-27 18:26:15.910: W/System.err(12681):    at java.lang.Thread.run(Thread.java:856)

This is line create exception after somewhile of receiving proper audio, as when I am trying to initiate it again so having exception res = this.track.write(buf, written, buf.length - written);

And this is how I am stoping and releasing my track

public void stopPlay() {
    Log.d("IAX2Audio", "stopPlay()");

    if (this.track == null)
        return;

    if (this.track != null) {
        //this.track.stop();
        //this.track.release();

        if (this.track != null
                && this.track.getState() != AudioTrack.STATE_UNINITIALIZED) {
            if (track.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) {
                track.stop();
                track.release();
            }
        }
    }

    try {
        if (this.playThread != null) {
            final Thread t = this.playThread;
            /* Setting this to null is the signal to the thread to exit. */
            this.playThread = null;
            t.join();
        }
    } catch (final InterruptedException e) {
        e.printStackTrace();
    }

}

Please find Updated Fixed solution for AndroidAudioInterface.java . AndroidAudioInterface.java

Deuteragonist answered 27/4, 2014 at 15:1 Comment(2)
Why are you using write() and playback functionality if your goal is to retrieve audio?Electrolyse
Actually I am making VOIP application , for that I am using AudioTrack write and playback for ringback functionality, let me add my java class for complete source code, that create problem to whole Android audio driver and the fixed wasnt done even after commenting release.Deuteragonist
D
5

It is a simple fix but might be an Android issue, please refer to my fix below

if (track != null && track.getState() != AudioTrack.STATE_UNINITIALIZED) {
    if (track.getPlayState() != AudioTrack.PLAYSTATE_STOPPED) {

        try{
            track.stop();
        }catch (IllegalStateException e)
        {
            e.printStackTrace();
        }

    }

    track.release();     
    am.setMode(AudioManager.MODE_NORMAL); 

    //track.release();
    //track = null;
}

and OnCreate

private AudioManager am;

am = (AudioManager)this.context.getSystemService(Context.AUDIO_SERVICE); 
am.setMode(AudioManager.MODE_NORMAL); 
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);

And always use AudioTrack in Thread as main thread will also hand your application

Deuteragonist answered 13/5, 2014 at 9:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.