How do I handle calls to AudioTrack from jni without crashing?

icecream :

I was trying to write to an AudioTrack from a jni callback, and I get a signal 7 (SIGBUS), fault addr 00000000.

I have looked at the Wolf3D example for odroid and they seem to use a android.os.Handler to post a Runnable that will do an update in the correct thread context. I have also tried AttachCurrentThread, but I fail in this case also.

It works to play the sound when running from the constructor even if I wrap it in a thread and then post it to the handler. When I do the "same" via a callback from jni it fails. I assume I am braeaking some rules, but I haven't been able to figure out what they are. So far, I haven't found the answer here on SO.

So I wonder if anyone knows how this should be done.

EDIT: Answered below.

The following code is to illustrate the problem.

Java:

package com.example.jniaudiotrack;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class JniAudioTrackActivity extends Activity {
    AudioTrack mAudioTrack;
    byte[] mArr;
    public static final Handler mHandler = new Handler();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mArr = new byte[2048];
        for (int i = 0; i < 2048; i++) {
            mArr[i] = (byte) (Math.sin(i) * 128);
        }

        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                11025,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_8BIT,
                2048,
                AudioTrack.MODE_STREAM);
        mAudioTrack.play();

        new Thread(new Runnable() {
            public void run() {
                mHandler.post(new Runnable() {
                    public void run() {
                        mAudioTrack.write(mArr, 0, 2048);
                        Log.i(TAG, "*** Handler from constructor ***");
                    }
                });
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                audioFunc();
            }
        }).start();
    }

    public native void audioFunc();

    @SuppressWarnings("unused")
    private void audioCB() {
        mHandler.post(new Runnable() {
            public void run() {
                mAudioTrack.write(mArr, 0, 2048);
                Log.i(TAG, "*** audioCB called ***");
            }
        });
    }

    private static final String TAG = "JniAudioTrackActivity";

    static {
        System.loadLibrary("jni_audiotrack");
    }
}

cpp:

#include <jni.h>

extern "C" {
    JNIEXPORT void Java_com_example_jniaudiotrack_JniAudioTrackActivity_audioFunc(JNIEnv* env, jobject obj);
}

JNIEXPORT void Java_com_example_jniaudiotrack_JniAudioTrackActivity_audioFunc(JNIEnv* env, jobject obj)
{
    JNIEnv* jniEnv;
    JavaVM* vm;
    env->GetJavaVM(&vm);
    vm->AttachCurrentThread(&jniEnv, 0);

    jclass cls = env->GetObjectClass(obj);
    jmethodID audioCBID = env->GetMethodID(cls, "audioCB", "()V");

    if (!audioCBID) {
        return;
    }

    env->CallVoidMethod(cls, audioCBID);
}

Trace snippet:

I/DEBUG   ( 1653): pid: 9811, tid: 9811  >>> com.example.jniaudiotrack <<<
I/DEBUG   ( 1653): signal 7 (SIGBUS), fault addr 00000000
I/DEBUG   ( 1653):  r0 00000800  r1 00000026  r2 00000001  r3 00000000
I/DEBUG   ( 1653):  r4 42385726  r5 41049e54  r6 bee25570  r7 ad00e540
I/DEBUG   ( 1653):  r8 000040f8  r9 41048200  10 41049e44  fp 00000000
I/DEBUG   ( 1653):  ip 000000f8  sp bee25530  lr ad02dbb5  pc ad012358  cpsr 20000010
I/DEBUG   ( 1653):          #00  pc 00012358  /system/lib/libdvm.so
icecream :

There seems to have been a memory problem. Making mAudioTrack and mArr static solved it. I was sending the wrong object to the callback. See comment by fadden. I have removed the call to AttachCurrentThread since it did not make any difference in this case.

Java:

package com.example.jniaudiotrack;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

public class JniAudioTrackActivity extends Activity {
    public AudioTrack mAudioTrack;
    public byte[] mArr;
    public static Handler mHandler = new Handler();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mArr = new byte[2048];
        for (int i = 0; i < 2048; i++) {
            mArr[i] = (byte) (Math.sin(i) * 128);
        }

        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    11025,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_8BIT,
                    2048,
                    AudioTrack.MODE_STREAM);
        mAudioTrack.play();

        new Thread(new Runnable() {
            public void run() {
                audioFunc();
            }
        }).start();
    }

    public native void audioFunc();

    @SuppressWarnings("unused")
    private void audioCB() {
        mHandler.post(new Runnable() {
            public void run() {
                mAudioTrack.write(mArr, 0, 2048);
                Log.i(TAG, "*** audioCB called ***");
            }
        });
    }

    private static final String TAG = "JniAudioTrackActivity";

    static {
        System.loadLibrary("jni_audiotrack");
    }
}

Cpp:

#include <jni.h>

extern "C" {
    JNIEXPORT void Java_com_example_jniaudiotrack_JniAudioTrackActivity_audioFunc(JNIEnv* env, jobject obj);
}

JNIEXPORT void Java_com_example_jniaudiotrack_JniAudioTrackActivity_audioFunc(JNIEnv* env, jobject obj)
{
    jclass cls = env->GetObjectClass(obj);
    jmethodID audioCBID = env->GetMethodID(cls, "audioCB", "()V");

    if (!audioCBID) {
        return;
    }

    env->CallVoidMethod(obj, audioCBID);
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to handle error without crashing function with axios?

From Dev

How do I use RxJS to process hundreds of requests without crashing?

From Dev

How do I keep a WKWebView object from crashing?

From Dev

How do I prevent script from crashing as a result of failed proc?

From Dev

How do I prevent my script from crashing if condition is not met?

From Dev

how do i stop my application from crashing

From Dev

How do I do a a,b,c = x.split(" ") without it crashing when only a and b can be assigned?

From Dev

How to mock an error from Observable without crashing?

From Dev

How do I retrieve the processor time in Linux without function calls?

From Python

How do I process very large file (13GB) in python without crashing?

From Dev

How do I check the value of a non-existent variable without crashing the program?

From Dev

How do i pass the ForEach array index through a NavigationLink in to another ForEach without it crashing?

From Dev

How do I show an unknown length nested array without crashing the browser?

From Dev

How do I clean ~500,000 records in Excel 2010 without crashing my PC?

From Dev

How Do I Enumerate Boot Entries without Crashing My Program in C?

From Dev

How do I handle a KeyError exception in python without exiting the dictionary?

From Dev

How do I handle these typedef's without warnings?

From Dev

How do a get the data from Haxe's http.customRequest without crashing?

From Java

How to handle error from network with retrofit calls

From Dev

How to handle asynchronous calls from useEffect

From Dev

How to handle errors from Stored Procedure calls

From Dev

How do I handle API calls with actions in the React.js Flux architecture and McFly?

From Dev

How do I handle multiple browser scripts making the same calls to the back-end service

From Dev

How do i handle sub sequential URL calls in RxJS that pass data to each other?

From Dev

How do I prevent Windows 8 File Explorer from regularly crashing (about every 10 Minutes)?

From

How do I prevent node.js from crashing? try-catch doesn't work

From Dev

How do I prevent Tkinter from crashing when my code loses internet

From Dev

How do I find calls to a function in Git from another file?

From Dev

how do I handle a specific output from systemctl?

Related Related

  1. 1

    How to handle error without crashing function with axios?

  2. 2

    How do I use RxJS to process hundreds of requests without crashing?

  3. 3

    How do I keep a WKWebView object from crashing?

  4. 4

    How do I prevent script from crashing as a result of failed proc?

  5. 5

    How do I prevent my script from crashing if condition is not met?

  6. 6

    how do i stop my application from crashing

  7. 7

    How do I do a a,b,c = x.split(" ") without it crashing when only a and b can be assigned?

  8. 8

    How to mock an error from Observable without crashing?

  9. 9

    How do I retrieve the processor time in Linux without function calls?

  10. 10

    How do I process very large file (13GB) in python without crashing?

  11. 11

    How do I check the value of a non-existent variable without crashing the program?

  12. 12

    How do i pass the ForEach array index through a NavigationLink in to another ForEach without it crashing?

  13. 13

    How do I show an unknown length nested array without crashing the browser?

  14. 14

    How do I clean ~500,000 records in Excel 2010 without crashing my PC?

  15. 15

    How Do I Enumerate Boot Entries without Crashing My Program in C?

  16. 16

    How do I handle a KeyError exception in python without exiting the dictionary?

  17. 17

    How do I handle these typedef's without warnings?

  18. 18

    How do a get the data from Haxe's http.customRequest without crashing?

  19. 19

    How to handle error from network with retrofit calls

  20. 20

    How to handle asynchronous calls from useEffect

  21. 21

    How to handle errors from Stored Procedure calls

  22. 22

    How do I handle API calls with actions in the React.js Flux architecture and McFly?

  23. 23

    How do I handle multiple browser scripts making the same calls to the back-end service

  24. 24

    How do i handle sub sequential URL calls in RxJS that pass data to each other?

  25. 25

    How do I prevent Windows 8 File Explorer from regularly crashing (about every 10 Minutes)?

  26. 26

    How do I prevent node.js from crashing? try-catch doesn't work

  27. 27

    How do I prevent Tkinter from crashing when my code loses internet

  28. 28

    How do I find calls to a function in Git from another file?

  29. 29

    how do I handle a specific output from systemctl?

HotTag

Archive