segfault when passing DirectByteBuffer via Audiorecord

276 views
Skip to first unread message

siliconeagle

unread,
Mar 18, 2010, 11:25:13 AM3/18/10
to android-ndk
Hi,

I am trying to get a basic audio passthru application going using NDK.
Though i get a segfault (I think it is in audio record). The code
works for about 10secs (passes about 100 x 4096 byte blocks) and then
crashes. I am very new to NDK so there is likely something(s) I am
missing. looks like the pointer is changing somewhere or some buffer
is filling up.

Also, are there any API docs for NDK (like for java sdk)? Haven't been
able to find a list of what is in NDK except for the include directory
- which doesn't have much info about the various functions.

--------------------- Java code -------------------------------------
public native void processBuffer(ByteBuffer input,ByteBuffer
output,int bytesRead);

private void passThruNative() {
int rintSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);

AudioRecord mRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_DEFAULT,
AudioFormat.ENCODING_DEFAULT,
rintSize
);

int tintSize = AudioTrack.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);

AudioTrack oTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
tintSize,
AudioTrack.MODE_STREAM);

if (mRecord.getState()==AudioRecord.STATE_INITIALIZED) {
mRecord.startRecording();

oTrack.play();
if (oTrack!=null && mRecord!=null) {
try {
//byte[] byteData = new byte[10000];
int bytesRead=-1;
isRunning=true;
cancel=false;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(rintSize);
ByteBuffer obyteBuffer = ByteBuffer.allocateDirect(rintSize);
while((bytesRead=mRecord.read( byteBuffer,rintSize ))>-1
&& !cancel) {
// Write the byte array to the track
processBuffer(byteBuffer,obyteBuffer,bytesRead);
byte[] byteData = new byte[bytesRead];
int i= obyteBuffer.remaining();
obyteBuffer.get( byteData,0,i);
oTrack.write(byteData,0,i);//output.array() -
DirectByteBuffer is protected
//obyteBuffer.clear();
//byteBuffer.clear();

obyteBuffer.rewind();
byteBuffer.rewind();

//Log.e("at1", "read:"+bytesRead+": buffsize:"+rintSize);
}

} catch (Exception e) {
Log.e("at1", "Passthru Exception:"+e.getMessage());
e.printStackTrace();
}
}
mRecord.stop();
mRecord.release();
} else {
this.runOnUiThread(new Runnable() { public void run()
{Toast.makeText(AudioTrack1.this, "record not initialised",
500).show();}});
}
// Done writing to the track
oTrack.flush();
oTrack.stop();
oTrack.release();
isRunning=false;
}
----------------------- Native code
---------------------------------------------------

void Java_net_robmunro_test_at1_AudioTrack1_processBuffer(JNIEnv* env,
jobject thiz,
jbyte* in_buffer,
jbyte* out_buffer,
jint size) {
//jbyte *coutput = (jbyte*) (*env)->GetByteArrayElements(env,
in_buffer, NULL);
//char *coutput = (char*)((*env)->GetDirectBufferAddress(in_buffer));
int i=0;
for (i=0;i<size;i++) {
//in_buffer=(char) ()
out_buffer[i]=in_buffer[i];
}
//(*env)->ReleaseByteArrayElements(env, out_buffer, (jbyte*)coutput,
0);

//return coutput;
}
----------------------- stacktrace & error log
---------------------------------------------------

I/ActivityManager( 68): Starting activity: Intent
{ action=android.intent.action.MAIN
categories={android.intent.category.LAUNCHER} flags=0x10200000
comp={net.robmunro.test.at1/net.robmunro.test.at1.AudioTrack1} }
D/dalvikvm( 68): GC freed 30845 objects / 1622880 bytes in 308ms
D/OpenSSLSessionImpl( 68): Freeing OpenSSL session
D/OpenSSLSessionImpl( 68): Freeing OpenSSL session
I/ActivityManager( 68): Start proc net.robmunro.test.at1 for
activity net.robmunro.test.at1/.AudioTrack1: pid=22921 uid=10068
gids={}
I/dalvikvm(22921): Debugger thread not active, ignoring DDM send
(t=0x41504e4d l=38)
I/WindowManager( 68): Screen status=true, current orientation=-1,
SensorEnabled=false
I/WindowManager( 68): needSensorRunningLp, mCurrentAppOrientation
=-1
D/AK8973 ( 41): Compass Start
D/Sensors ( 68): open_akm, fd=132
D/Sensors ( 68): sensors=00000001, real=00000001
D/Sensors ( 68): using /dev/input/event4 (name=compass)
D/Sensors ( 68): data__data_open: fd = 136
I/WindowManager( 68): Enabling listeners
I/dalvikvm(22921): Debugger thread not active, ignoring DDM send
(t=0x41504e4d l=46)
D/dalvikvm(22921): Trying to load lib /data/data/net.robmunro.test.at1/
lib/libat1.so 0x4354ade0
D/dalvikvm(22921): Added shared lib /data/data/net.robmunro.test.at1/
lib/libat1.so 0x4354ade0
D/dalvikvm(22921): No JNI_OnLoad found in /data/data/
net.robmunro.test.at1/lib/libat1.so 0x4354ade0
W/InputManagerService( 68): Got RemoteException sending
setActive(false) notification to pid 22909 uid 10068
I/ActivityManager( 68): Displayed activity
net.robmunro.test.at1/.AudioTrack1: 1003 ms
W/InputManagerService( 68): Ignoring hideSoftInput of:
com.android.internal.view.IInputMethodClient$Stub$Proxy@43871540
W/Rosie ( 122): mAddHtcWidgetByOtherActivity = false,
mIsOpenSlideWhenLeaveLaunch = true
D/dalvikvm( 122): GC freed 10847 objects / 850144 bytes in 273ms
D/AudioHardwareMSM72XX(16020): audpre_index = 7, tx_iir_index = 14
D/HTC Acoustic(16020): msm72xx_enable_audpre: 0x0000
I/AudioHardwareMSM72XX(16020): AUDIO_START: start kernel pcm_in
driver.
D/dalvikvm(22921): +++ not scanning '/system/lib/libwebcore.so' for
'processBuffer' (wrong CL)
D/dalvikvm(22921): +++ not scanning '/system/lib/libmedia_jni.so' for
'processBuffer' (wrong CL)
I/AudioHardwareMSM72XX(16020): AUDIO_START: start kernel pcm_out
driver.
D/dalvikvm(16026): GC freed 672 objects / 103344 bytes in 194ms
W/AudioFlinger(16020): AudioRecordThread: buffer overflow
D/libc-abort(22921): abort() called in pid 22921
I/DEBUG (22723): *** *** *** *** *** *** *** *** *** *** *** *** ***
*** *** ***
I/DEBUG (22723): Build fingerprint: 'tmeu/htc_hero/hero/hero:1.5/
CUPCAKE/69351:user/release-keys'
I/DEBUG (22723): pid: 22921, tid: 22930 >>> net.robmunro.test.at1
<<<
I/DEBUG (22723): signal 11 (SIGSEGV), fault addr deadbaad
I/DEBUG (22723): r0 00000003 r1 deadbaad r2 00000027 r3 ffff6180
I/DEBUG (22723): r4 ffff6158 r5 afe2ff28 r6 afe39dd0 r7 00000000
I/DEBUG (22723): r8 00000061 r9 455eccbc 10 42168cbc fp 451bfbbc
I/DEBUG (22723): ip 0000001c sp 451bf8e0 lr afe1ff33 pc
afe1066a cpsr 20000030
I/DEBUG (22723): #00 pc 0001066a /system/lib/libc.so
I/DEBUG (22723): #01 pc 00006546 /system/lib/libcutils.so
I/DEBUG (22723): #02 pc 00048cac /system/lib/libdvm.so
I/DEBUG (22723): #03 pc 00015d44 /system/lib/libdvm.so
I/DEBUG (22723): #04 pc 0001476c /system/lib/libdvm.so
I/DEBUG (22723): #05 pc 00014dfc /system/lib/libdvm.so
I/DEBUG (22723): #06 pc 00015c68 /system/lib/libdvm.so
I/DEBUG (22723): #07 pc 0001541c /system/lib/libdvm.so
I/DEBUG (22723): #08 pc 000157f0 /system/lib/libdvm.so
I/DEBUG (22723): #09 pc 00015958 /system/lib/libdvm.so
I/DEBUG (22723): #10 pc 0005a4ac /system/lib/libdvm.so
I/DEBUG (22723): #11 pc 0005a5cc /system/lib/libdvm.so
I/DEBUG (22723): #12 pc 0005a6cc /system/lib/libdvm.so
I/DEBUG (22723): #13 pc 00012790 /system/lib/libdvm.so
I/DEBUG (22723): #14 pc 00017b9c /system/lib/libdvm.so
I/DEBUG (22723): #15 pc 000175e0 /system/lib/libdvm.so
I/DEBUG (22723): #16 pc 000523dc /system/lib/libdvm.so
I/DEBUG (22723): #17 pc 000523fa /system/lib/libdvm.so
I/DEBUG (22723): #18 pc 000473a4 /system/lib/libdvm.so
I/DEBUG (22723): #19 pc 0000f880 /system/lib/libc.so
I/DEBUG (22723): #20 pc 0000f3f4 /system/lib/libc.so
I/DEBUG (22723): stack:
I/DEBUG (22723): 451bf8a0 00000000
I/DEBUG (22723): 451bf8a4 00000000
I/DEBUG (22723): 451bf8a8 afe39f90
I/DEBUG (22723): 451bf8ac afe39fe4
I/DEBUG (22723): 451bf8b0 00000000
I/DEBUG (22723): 451bf8b4 afe13e4d /system/lib/libc.so
I/DEBUG (22723): 451bf8b8 00000000
I/DEBUG (22723): 451bf8bc d03c14cd
I/DEBUG (22723): 451bf8c0 00000000
I/DEBUG (22723): 451bf8c4 ffff6158
I/DEBUG (22723): 451bf8c8 afe2ff28 /system/lib/libc.so
I/DEBUG (22723): 451bf8cc afe39dd0
I/DEBUG (22723): 451bf8d0 00000000
I/DEBUG (22723): 451bf8d4 afe10663 /system/lib/libc.so
I/DEBUG (22723): 451bf8d8 df002777
I/DEBUG (22723): 451bf8dc e3a070ad
I/DEBUG (22723): #00 451bf8e0 00000000
I/DEBUG (22723): 451bf8e4 afbc10fd /system/lib/liblog.so
I/DEBUG (22723): 451bf8e8 afbc30b8
I/DEBUG (22723): 451bf8ec 00000000
I/DEBUG (22723): 451bf8f0 000000b4
I/DEBUG (22723): 451bf8f4 fffffbdf
I/DEBUG (22723): 451bf8f8 400082e0
I/DEBUG (22723): 451bf8fc 4355ec20
I/DEBUG (22723): 451bf900 43540018
I/DEBUG (22723): 451bf904 afb0654b /system/lib/libcutils.so
I/DEBUG (22723): #01 451bf908 43540010
I/DEBUG (22723): 451bf90c 000000a8
I/DEBUG (22723): 451bf910 451bf934
I/DEBUG (22723): 451bf914 400082e0
I/DEBUG (22723): 451bf918 4355ec28
I/DEBUG (22723): 451bf91c 400082c8
I/DEBUG (22723): 451bf920 00000000
I/DEBUG (22723): 451bf924 ad048caf /system/lib/libdvm.so
I/DEBUG (22723): debuggerd committing suicide to free the zombie!
I/ActivityManager( 68): Process net.robmunro.test.at1 (pid 22921)
has died.
I/WindowManager( 68): WIN DEATH: Window{4372c3d8
net.robmunro.test.at1/net.robmunro.test.at1.AudioTrack1 paused=false}

fadden

unread,
Mar 18, 2010, 3:57:42 PM3/18/10
to android-ndk
On Mar 18, 8:25 am, siliconeagle <rrmu...@gmail.com> wrote:
> void Java_net_robmunro_test_at1_AudioTrack1_processBuffer(JNIEnv* env,
>                                                                                                 jobject thiz,
>                                                                                                 jbyte* in_buffer,
>                                                                                                 jbyte* out_buffer,
>                                                                                                 jint size) {
>         //jbyte *coutput = (jbyte*) (*env)->GetByteArrayElements(env,
> in_buffer, NULL);
>         //char *coutput = (char*)((*env)->GetDirectBufferAddress(in_buffer));
>         int i=0;
>         for (i=0;i<size;i++) {
>                 //in_buffer=(char) ()
>                 out_buffer[i]=in_buffer[i];
>         }
>         //(*env)->ReleaseByteArrayElements(env, out_buffer, (jbyte*)coutput,
> 0);
>
>         //return coutput;}

Java does not pass a jbyte* to native code; it passes some flavor of
object. If you were passing in a byte[], it would be a jbyteArray
object. You would convert that to a jbyte* with GetByteArrayElements,
and double-check the array length with GetArrayLength.

However, looking at the Java code, it appears you're actually passing
a DirectByteBuffer object in. For that, you would use
GetDirectByteBufferAddress and GetDirectByteBufferCapacity to get the
address and size of the buffer.

The existing code appears to be copying a bunch of bytes from one
point in the virtual heap to another, trampling all over things. The
process ends when something in libcutils calls abort():

> W/AudioFlinger(16020): AudioRecordThread: buffer overflow
> D/libc-abort(22921): abort() called in pid 22921

...

siliconeagle

unread,
Mar 18, 2010, 8:43:23 PM3/18/10
to android-ndk
so i make another method, processBuffer2
a) doesnt compile : /home/robm/devel/android/at1j//jni/at1.c:70:
undefined reference to `__android_log_print' - do i need to specify
android/log.h in a makefile soewhere?
b). when i comment out that line i get a segfault straight away.
--------------code -------------------------------
#include <android/log.h>
....
void Java_net_robmunro_test_at1_AudioTrack1_processBuffer2(JNIEnv*

env,
jobject thiz,
jbyte* in_buffer,
jbyte* out_buffer,
jint size) {
jbyte *cinput = (jbyte*)(*env)->GetDirectBufferAddress(env,
in_buffer);
jlong size1 = (*env)->GetDirectBufferCapacity(env, in_buffer);
int i=0;
for (i=0;i<size1;i++) {
out_buffer[i]=cinput[i];
}
__android_log_print(ANDROID_LOG_DEBUG, "at1", "Could not string(%s)
\n");
}

On Mar 18, 7:57 pm, fadden <fad...

David Turner

unread,
Mar 18, 2010, 8:58:43 PM3/18/10
to andro...@googlegroups.com
On Thu, Mar 18, 2010 at 5:43 PM, siliconeagle <rrm...@gmail.com> wrote:
so i make another method, processBuffer2
a) doesnt compile : /home/robm/devel/android/at1j//jni/at1.c:70:
undefined reference to `__android_log_print' - do i need to specify

You need to add LOCAL_LDLIBS += -llog to your Android.mk
 
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


siliconeagle

unread,
Mar 19, 2010, 12:50:43 PM3/19/10
to android-ndk
Thanks heaps guys i finally got it working.

does anyone have any suggestions/links on the best place to find info/
api docs for the ndk?

Should i just be looking at standard C and JNI docs or just the
include header files?

is there a website like for the java api docs?

On Mar 19, 12:58 am, David Turner <di...@android.com> wrote:

> > android-ndk...@googlegroups.com<android-ndk%2Bunsu...@googlegroups.com>

Andrej Sarkic

unread,
Mar 19, 2010, 1:02:23 PM3/19/10
to andro...@googlegroups.com
careful, though. log.h is only defined for android-5, which corresponds to 2.0. Make sure your platform is 5. This is something I ran into as well.

Thanks,
Andrej

To unsubscribe from this group, send email to android-ndk...@googlegroups.com.

David Turner

unread,
Mar 19, 2010, 1:11:45 PM3/19/10
to andro...@googlegroups.com
On Fri, Mar 19, 2010 at 10:02 AM, Andrej Sarkic <andrej...@gmail.com> wrote:
careful, though. log.h is only defined for android-5, which corresponds to 2.0. Make sure your platform is 5. This is something I ran into as well.

This is not true anymore. If you have a recent NDK, you will be able to use it for all platforms (i.e. starting with android-3)

What happened is that the log functionality was not exposed by earlier NDK revisions, but the early system images still support it in a stable way.

Andrej Sarkic

unread,
Mar 19, 2010, 2:25:43 PM3/19/10
to andro...@googlegroups.com
Thanks! That actually worked for me, too (adding -llog). Now if I only I could figure out why I'm not seeing it in logcat, v. the Java Log which I do see there....
Reply all
Reply to author
Forward
0 new messages