Copy part of an array char in jbyte

1,802 views
Skip to first unread message

Антон Иванов

unread,
Jun 8, 2011, 4:43:11 AM6/8/11
to andro...@googlegroups.com
There is an array char * buffer. I need to copy "n" elements of char array, from element "k" to a jbyte. Now the code is as follows:
jbyte * bytes = (* env) -> GetByteArrayElements (env, array, NULL);
memmove (bytes, (jbyte *) buffer, buffer_size);
 (* env) -> ReleaseByteArrayElements (env, array, (jbyte *) bytes, 0);

memmove copies the elements from the beginning of the array, but I need to copy from a certain element, such as 16384.
Is it possible? How to do it? Thanks in advance.

ThaMe90

unread,
Jun 8, 2011, 5:24:01 AM6/8/11
to android-ndk
http://java.sun.com/docs/books/jni/html/functions.html#64717
And look up GetByteArrayRegion().
This lets you specify which region of bytes you wish to retrieve:

jbyte* bytes = (*env)->GetByteArrayRegion(env, array, start_Index,
num_Bytes, pointer_To_Buffer);
This sets num_Bytes bytes in the buffer pointed to by
pointer_To_Buffer, with the first byte being the byte at index
start_Index of the array (in your example this would be 16384).

nowrin anwar

unread,
Jun 8, 2011, 5:26:11 AM6/8/11
to andro...@googlegroups.com
use GetByteArrayRegion(JNIEnv *env, jbytearray, jsize start, jsize len, jbyte *buf);)


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/eWlnYlhjbDNWVnNK.
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.

Антон Иванов

unread,
Jun 8, 2011, 5:55:10 AM6/8/11
to andro...@googlegroups.com
Understood. Thank you very much. Another 2 questions are:
1. If I pass through JNI in the NDK array, then in the NDK modify the array using this function, the array in the Java change?
2. Can I somehow clear the array in Java, so that every time the NDK data is written in pure array?
Maybe the questions are simple, but I have not studied the entire JNI, so help me.

2011/6/8 nowrin anwar <joyi...@gmail.com>

ThaMe90

unread,
Jun 8, 2011, 5:59:05 AM6/8/11
to android-ndk
What the getByteArrayRegion method does (as any other get method) is
place the value from the Java VM Stack onto the C stack.
They don't share their memory space, thus the answer on your first
question would be no. If you want the changes to be passed up into the
Java layer, you need to call the setByteArrayRegion method.

The answer to your second question I don't know for sure, but I don't
think that is possible, as you don't get the array from Java. If I am
not mistaken, you only pass a reference to the data to the JNI code,
and hence you still need to get the data yourself. But I am not
exactly sure about that.

On 8 jun, 11:55, Антон Иванов <wkybo...@gmail.com> wrote:
> Understood. Thank you very much. Another 2 questions are:
> 1. If I pass through JNI in the NDK array, then in the NDK modify the
> array using
> this function, the array in the Java change?
> 2. Can I somehow clear the array in Java, so that every time the NDK data is
>  written in pure array?
> Maybe the questions are simple, but I have not studied the entire JNI, so help
> me.
>
> 2011/6/8 nowrin anwar <joyit...@gmail.com>
>
>
>
>
>
>
>
> > use GetByteArrayRegion(JNIEnv *env, jbytearray, jsize start, jsize len,
> > jbyte *buf);)
>

Антон Иванов

unread,
Jun 8, 2011, 6:15:33 AM6/8/11
to andro...@googlegroups.com
I'm confused:) The problem is that I get a char buffer. Its size is very large. I need to transfer some part of this buffer in Java. Ie we must take a piece of this buffer, since we assume 16,384 element and ending element 32000. How can I do better? If I just create jbyteArray in the NDK and releases it in Java, then at some iteration throws out an error.The error occurs because I have these parts buffer to pass many times. If I create a byte[] in Java and release it into the NDK, and then begin to change, the more I don `t know how to clean it. 
Initially I tried this: 
                          
jbyte * bytes = (* env) -> GetByteArrayElements (env, array, NULL); 

                          
memmove (bytes, (jbyte *) buffer, buffer_size); 
  
(* Env) -> ReleaseByteArrayElements (env, array, (jbyte *) bytes, 0); 
  
(* Env) -> CallStaticVoidMethod (env, cls, mid, buffer_size); 
But in this case, the entire buffer is transmitted, and it is very big (more than 40 million). I need only a part of buffer. 
help. Tell me how you would transfer a part of buffer from NDK to Java many times.


2011/6/8 ThaMe90 <thepro...@gmail.com>

ThaMe90

unread,
Jun 8, 2011, 6:27:25 AM6/8/11
to android-ndk
That depends on if you wish to specify how many elements you want to
get from the >40 million and where to start getting them from in Java,
I'd pass those values along as parameters to the native function. Then
you could get the specified number of bytes starting from the index
you passed along. This way, you won't have the >40 million bytes to
work with in your native code.

Or you could just split up the large array into the parts you need in
the Java code with System.arraycopy(sourceArray, sourceStartIndex,
destination, destinationStartIndex, length); and just pass the
destination array to the native layer.

Splitting arrays in the native code is something I have yet to try out
myself, so I can't help you on that.

Btw, C doesn't have a byte default type, but it's equivalent is an
unsigned char.

On 8 jun, 12:15, Антон Иванов <wkybo...@gmail.com> wrote:
> I'm confused:) The problem is that I get a char buffer. Its size is very
> large. I need to transfer some part of this buffer in Java. Ie we must take
> a piece of this buffer, since we assume 16,384 element and ending element
> 32000. How can I do better? If I just create jbyteArray in the NDK and
> releases it in Java, then at some iteration throws out an error.The error
> occurs because I have these parts buffer to pass many times. If I create a
> byte[] in Java and release it into the NDK, and then begin to change, the
> more I don `t know how to clean it.
> Initially I tried this:
>                           jbyte * bytes = (* env) -> GetByteArrayElements
> (env, array, NULL);
>
>                           memmove (bytes, (jbyte *) buffer, buffer_size);
>   (* Env) -> ReleaseByteArrayElements (env, array, (jbyte *) bytes, 0);
>   (* Env) -> CallStaticVoidMethod (env, cls, mid, buffer_size);
> But in this case, the entire buffer is transmitted, and it is very big (more
> than 40 million). I need only a part of buffer.
> help. Tell me how you would transfer a part of buffer from NDK to Java many
> times.
>
> 2011/6/8 ThaMe90 <theprophes...@gmail.com>

Антон Иванов

unread,
Jun 8, 2011, 6:39:32 AM6/8/11
to andro...@googlegroups.com
Well, I have another solution, I create a Java array on 40000000 elements and just gowrite buffer. The only problem is that the CPU load goes very high, about 30% andstart playing audio lag. Is there anything in this case, the decision as to reduce the load on the processor and memory?

2011/6/8 ThaMe90 <thepro...@gmail.com>

ThaMe90

unread,
Jun 8, 2011, 7:06:46 AM6/8/11
to android-ndk
Well, all I can say is that I don't know why you need an array with 40
million elements, as it takes a lot of memory.
Try dividing the array up into smaller arrays? Only place I could
imagine when you could need such an array is when you try to load an
audio file. Even then I'd not use your approach of one large array.

On the audio, I don't know what kind of latency you are getting, but I
am getting a latency of > 300 ms with real time audio (PCM 16bit @
8kHz).
The latency is something you have to accept in my opinion, as Android
doesn't offer any reliable way of reducing audio latency. Even on
Android 2.3 with it's low-latency audio feature, I am not able to do
better than 350 ms of latency :<

On 8 jun, 12:39, Антон Иванов <wkybo...@gmail.com> wrote:
> Well, I have another solution, I create a Java array on 40000000 elements
> and just gowrite buffer. The only problem is that the CPU load goes very
> high, about 30% andstart playing audio lag. Is there anything in this case,
> the decision as to reduce the load on the processor and memory?
>
> 2011/6/8 ThaMe90 <theprophes...@gmail.com>

Антон Иванов

unread,
Jun 8, 2011, 8:19:12 AM6/8/11
to andro...@googlegroups.com

I need a large buffer because the library for decoding I use decodes all in one buffer. As I wrote - I have another option, to send only part of the buffer each time, but I do not know how to do it. I do not understand your option. You can write your code example how would you solved this problem? Please do. thanks in advance

08.06.2011 14:06 пользователь "ThaMe90" <thepro...@gmail.com> написал:

ThaMe90

unread,
Jun 8, 2011, 8:56:40 AM6/8/11
to android-ndk
Depends on how you generate your data.
If it is from a file, read the file x bytes at a time and continue
until you get an end-of-file (can be done with an byteinputstream set
on the file).
If it is over the network, you have to send it in smaller packages
anyway, so just receive those.
If you generate your own sound, generate it in smaller bits.

I don't see why you have to specify the whole buffer in one time.
Unless you try to play your audio statically. What I mean is that you
have to play your audio in stream mode.

What exactly do you use to play audio?

On 8 jun, 14:19, Антон Иванов <wkybo...@gmail.com> wrote:
> I need a large buffer because the library for decoding I use decodes all in
> one buffer. As I wrote - I have another option, to send only part of the
> buffer each time, but I do not know how to do it. I do not understand your
> option. You can write your code example how would you solved this problem?
> Please do. thanks in advance
> 08.06.2011 14:06 пользователь "ThaMe90" <theprophes...@gmail.com> написал:

Антон Иванов

unread,
Jun 8, 2011, 9:17:59 AM6/8/11
to andro...@googlegroups.com

I compiled the open source library. give it a file name, and she gives me a buffer, but at each iteration, it writes the new part of the buffer in the same array. understand? so I think that the only way to take part of the buffer of char and give java. but how? the entire buffer can give, but if the size reaches 40 million.

08.06.2011 15:56 пользователь "ThaMe90" <thepro...@gmail.com> написал:

ThaMe90

unread,
Jun 8, 2011, 9:23:47 AM6/8/11
to android-ndk
When it starts a new iteration, does it give you an event or is it
possible for you to set a callback?
I ask this because I can't possible see what you mean with "I compiled
the open source library", as if you imply that there is only one...

On 8 jun, 15:17, Антон Иванов <wkybo...@gmail.com> wrote:
> I compiled the open source library. give it a file name, and she gives me a
> buffer, but at each iteration, it writes the new part of the buffer in the
> same array. understand? so I think that the only way to take part of the
> buffer of char and give java. but how? the entire buffer can give, but if
> the size reaches 40 million.
> 08.06.2011 15:56 пользователь "ThaMe90" <theprophes...@gmail.com> написал:
> > --...
>
> meer lezen >>

Антон Иванов

unread,
Jun 8, 2011, 9:43:18 AM6/8/11
to andro...@googlegroups.com

It's very simple - I write a while loop, in which the function of obtaining a buffer, for example: while (get buffer) in the performance of the functions of the new buffer is written in the same array. understand?Library work is absolutely essential. importantly, the fact that every time I get more and more buffer, ie all bytes are collected into a single array. I pass the whole array, but then the memory takes under 50 megabytes. I need to understand how to extract from the whole array of only a part. you help with this?

08.06.2011 16:23 пользователь "ThaMe90" <thepro...@gmail.com> написал:

ThaMe90

unread,
Jun 8, 2011, 9:55:26 AM6/8/11
to android-ndk
From what I understand is that you put the data you get from the
library in one big array yourself.

I'd do this (from what I understood):

byte[] buffer = new byte[bufferLength];
while(moreData){
// I don't know the exact calls, so I just improvise here.
library.get(buffer);
// Process the data you got from the buffer.
processBuffer(buffer);
// Check if there is more data.
moreData = library.isEmpty();
}

This gets you smaller arrays every time the loop runs. As I mentioned,
I don't know what library you use, so see this as pseudo-code.
> 08.06.2011 16:23 пользователь "ThaMe90" <theprophes...@gmail.com> написал:

Антон Иванов

unread,
Jun 8, 2011, 10:36:40 AM6/8/11
to andro...@googlegroups.com

almost true, but it will not work. I initially configured the library for a buffer in a certain char. then at each iteration library itself writes the data in this char. char increases. question: how to use jni to get a certain part of buffer and give java. understand?

08.06.2011 16:55 пользователь "ThaMe90" <thepro...@gmail.com> написал:

ThaMe90

unread,
Jun 8, 2011, 10:40:14 AM6/8/11
to android-ndk
I guess it is not possible, unless you are able to feed the library a
new char to fill each time you get it. If it is only possible to set
the char once, then it is impossible to do what you want to do.

On 8 jun, 16:36, Антон Иванов <wkybo...@gmail.com> wrote:
> almost true, but it will not work. I initially configured the library for a
> buffer in a certain char. then at each iteration library itself writes the
> data in this char. char increases. question: how to use jni to get a certain
> part of buffer and give java. understand?
> 08.06.2011 16:55 пользователь "ThaMe90" <theprophes...@gmail.com> написал:
Reply all
Reply to author
Forward
0 new messages