Mix byte array android - java

I would like to mix audio byte array, but I didn't succeed to sum the array.(note i already added some silent bytes of 0 as padding before).
I have an ArrayList of byte[] which contains:
the first byte[] is header (44 bytes).
Following byte[] are raw data byte array to be mixed
Here is my code:
ArrayList<byte[]> ListAudio = new ArrayList<byte[]>();
byte[] header= WriteHeader(); //wav header 44 bytes
ListAudio.add(header);
for (byte[] b : audioTreatment.ListDataByte) {
ListAudio.add(b);
}
//calculate total length of audio
int length = 0;
for (byte[] array : ListAudio) {
length += array.length;
}
final int len = length;
final byte[] mixBytes = new byte[len];
for (byte[] array : ListAudio) {
for (int i = 44; i < len; ++i) {
mixBytes[i] += array[i];
// mixBytes[i]=(byte) ((bytes1[i]+bytes2[i]) / 2);
}
}
I found somewhere that the method to mix digital byte array is :
mixBytes[i]=(byte) ((bytes1[i]+bytes2[i]) / 2);
I don't arrive to include the calcul above, to sum the byte array.
How can i sum the bytes array from my ArrayList ?

you have to declare your sources to merge them
byte[] source1 = ListAudio.get(0); //first from list
byte[] source2 = ListAudio.get(1); //second from list
int length = Math.min(source1.length, source2.length);//length of new array
length = length - 44; //skipping 44 byte
byte[] dest = new byte[length];
for(int index = 0; index < length; index ++){
byte b1 = source1[index+44];
byte b2 = source2[index+44];
dest[index] = (byte) ((b1+b2) / 2);
}
That would merge the first two byte[] from your list.
If you want to merge other sources you can change them by selecting other byte[] from your List.
HINT
The length of the destination is declared as Math.min(a,b) but you can fill missing bytes with zeros if you want...
if you want to merge all arrays, you have to adjust your merge operation
mixing two bytes: mixBytes[i]=(byte) ((bytes1[i]+bytes2[i]) / 2);
mixing three bytes: mixBytes[i]=(byte) ((bytes1[i]+bytes2[i]+bytes3[i]) / 3);
mixing N bytes: mixBytes[i]=(byte) ((bytes1[i]+bytes2[i]+bytes3[i]+...+bytesN[i]) / N);
ok, for your code snipped it would be:
int length = ...;//length of result, either min or max as mentioned above, see HINT
byte[] mixBytes = new byte[length];
int amountAudio = ListAudio.size(); //amount of tracks in your list aka 'N'
int sum;
for(int index = 0; index < length; index++){
sum = 0;
for(byte[] source: ListAudio){
//adding all byte into one big integer
sum = sum + source[index]; //NOTE: watch for indexOutOfBoundsException
}
//afterward divide the big int through amount of Audio tracks in your list
mixBytes[index] = (byte)(sum / amountAudio);
}

Related

Retrieving data from byte Array

I'm trying to implement the tail program and want to print the last n bytes of a file. I've used a RandomAccessFile variable to store the data from the text file. When I try to retrieve the data and print it to the console, I'm getting something like this:
-n1
65109710979710979710810979710810510510979710910659711010510979711410011897114107109797114100119111108102106597114111110
How does on properly retrieve the data from the byte array?
This is my code:
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte[] b = new byte[n];
raf.readFully(b, 0, n);
for (int i = 0; i < n; i++) {
System.out.print(b[i]);
}
You are printing the byte value. To convert e.g. an array of bytes to a String that you can print on System.out.println try the following:
System.out.println(new String(b));
If you wish to convert each byte (as in your loop) to a printable charyou can do the following conversion:
for (int i = 0; i < 10; i++) {
char c = (char) (b[i] & 0xFF);
System.out.print(c);
}
A byte is simply one byte in size (8 bits) whereas a char in Java i 16 bits (2 bytes). Therefore the printed bytes does not make sense, it is not an entire character.
See this link for more info.

send a big byte array through java socket

I have a big byte array of length more than 1200000. I want to send it by DataOutputStream, and receive at client by DataInputStream.
I'm using the code
out.write(outData)
in.readFully(inData)
out is DataOutputStream, in is DataInputStream, outData is the byte array I want to send.
When I run the program, if the length of byte array is around 120000, the array can be sent, but when the length becomes 1200000, the server cant receive the array. Should I split the big array into some small ones?
I tried such code below, but it still not working.
out.writeInt(outData.length);
int start = 0;
int len = 0;
int count = outData.length;
while (count > 0) {
if (count < 4096)
len = count;
else len = 4096;
out.write(outData, start, len);
start += len;
count -= len;
}
and
int length=in.readInt();
byte[] inData=new byte[length];
in.readFully(inData);
Can somebody help? Thanks.
In writer:
for(int i=0;i<length;i++){
dataoutputstream.writeByte(bytearray[i]);
}
In reader:
for(int i=0;i<length;i++){
bytearray[i]=datainputstream.readByte();
}

Arraylist in a Arraylist

How is it possible to store data (bytes) input like this:
input data (bytes) : 01 23 45 and 67 89 10
At the end Arraylist row : [[01,23,45],[67,89,10]]
// declaration
List<List<Byte>> row = new ArrayList<List<Byte>>();
List<Byte> myBytes = new ArrayList<Byte>();
int j=0;
// code before this defines the arraylengt to cut the buffer in pieces of 3 bytes
// and clears the Mybytes arraylist to be able to fill the buffer with new values
if(arrayLength > 0)
{
myBytes.add(value); // fill first arraylist (buffer) with byte value (for example: 01)
if(arrayLength == 1) // when buffer myBytes is full (with values 01 23 45) write value to position j in the new arraylist
{
row.add(j,new ArrayList<Byte>());
row.set(j,myBytes);
j +=j;
}
arrayLength -= 1; // for cutting the buffer in pieces of 3 bytes
}
Thank you for helping me !!
Just use an Arraylist with an Array of Bytes new ArrayList<Byte[]>();. It's a good way to produce a [n][3]-Matrix.
I'd suggest just using a matrix of size [n][3]. You can make sure that it stays as a byte by adding ifs, and must make it an int matrix that way it can have as many rows as you want.
I found the answer, use a arraylist to buffer the values convert to byte array and place them in a other arraylist. Thanks guys !
Note: Make shure u use myBytes.clear();
Here is my code:
if(bool == true)
{
myBytes.add(value); // buffer
if(arrayLength == 1)
{
byte[] data = new byte[myBytes.size()];
for (int i = 0; i < data.length; i++)
{
data[i] = (byte) myBytes.get(i);
}
row.add(data);
}
arrayLength -= 1;
}

How to convert image to Boolean Array in Java (Android)?

I'm trying to store a 32 x 32 Boolean array in a 32 x 32 black and white image (either bitmap or PNG), to then be mapped to a Boolean[32][32] array with black pixels being true and white being false.
This is to store frames of animation to display on a virtual 32 x 32 display. Here's what I have so far below.
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), R.raw.f1);
bmp.compress(Bitmap.CompressFormat.PNG, 100, o_stream);
byte[] byteArray = o_stream.toByteArray();
What do I do with byteArray to make it a Boolean[32][32] array or am I going about this all wrong in the first place?
While I never did anything with images (so I don't know if this is anything close to what one should do to get the black-and-white of a pic), I suppose you need a rule to decide whether a pixel is closer to black or closer to white. But I'm curious, how can a byte represent a color? Even if it's RGB, you need at least three bytes, don't you?
if(src!= null){
ByteArrayOutputStream os=new ByteArrayOutputStream();
src.compress(android.graphics.Bitmap.CompressFormat.PNG, 100,(OutputStream) os);
byte[] byteArray = os.toByteArray();
//Log.d("byte=",""+byteArray.length);//returns length.
//str = Base64.encodeToString(byteArray,Base64.DEFAULT);//returns string
}
where src is the bitmap....
If you just want to encode an array of Booleans into a bitmap to save storage space, why use an image? That's a lot of extra overhead. Why not just create a bitmap yourself, like this:
Boolean[][] booleanArray = ... // this is your Boolean array
int[] bits = new int[32]; // One int holds 32 bits
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
if (booleanArray[i][j]) {
// Set bit at the corresponding position in the bits array
bits[i] |= 1 << j;
}
}
}
// Now you have the data in a int array which you can write to a file
// using DataOutputStream. The file would contain 128 bytes.
// To recreate the Boolean[32][32] from the int array, do this:
Boolean[][] booleanArray = new Boolean[32][32];
int[] bits = ... // This is the data you read from the file using DataInputStream
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
if ((bits[i] & (1 << j)) != 0) {
// Set corresponding Boolean
booleanArray[i][j] = true;
}
}
}

Converting array with samples into byte array

I have two-dimensional array of integers. First index indicates the number of channels. The second one indicates the number of sample in the channel. How can I save this array into the audio file? I know, I have to convert it to byte array, but I have no idea how to do that.
// edit
More info. I already have a class for drawing a waveform. It is here:
http://javafaq.nu/java-example-code-716.html
now I want to cut part of this wave and save it to the new file. So I have to cut part of int[][] samplesContainer, convert it to byte array (I don't know how) and then save it to file with the same format as audioInputStream.
// edit
OK. So the biggest problem is to write inverted function to this one:
protected int[][] getSampleArray(byte[] eightBitByteArray) {
int[][] toReturn = new int[getNumberOfChannels()][eightBitByteArray.length / (2 * getNumberOfChannels())];
int index = 0;
//loop through the byte[]
for (int t = 0; t < eightBitByteArray.length;) {
//for each iteration, loop through the channels
for (int a = 0; a < getNumberOfChannels(); a++) {
//do the byte to sample conversion
//see AmplitudeEditor for more info
int low = (int) eightBitByteArray[t];
t++;
int high = (int) eightBitByteArray[t];
t++;
int sample = (high << 8) + (low & 0x00ff);
if (sample < sampleMin) {
sampleMin = sample;
} else if (sample > sampleMax) {
sampleMax = sample;
}
//set the value.
toReturn[a][index] = sample;
}
index++;
}
return toReturn;
}
I don't understand why there is second incrementation of t, after high. I also have no idea how can i get high and low from sample.
The code you posted reads a sample stream, byte by byte, into the samples array. The code assumes that, in the stream, every two 8-bit bytes form a 16-bit sample, and that there is one sample for each of the NumOfChannels channels.
So, given an array of samples like the one returned by that code,
int[][] samples;
and a byte array for streaming,
byte[] stream;
you might build the converse stream of bytes this way
for (int i=0; i<NumOfSamples; i++) {
for (int j=0; j<NumOfChannels; j++) {
int sample=samples[i][j];
byte low = (byte) (sample & 0xff) ;
byte high = (byte) ((sample & 0xff00 ) >> 8);
stream[((i*NumOfChannels)+j)*2] = low;
stream[(((i*NumOfChannels)+j)*2)+1] = high;
}
}

Categories