In my android app I receive from a sensor data with the size of 8 Byte
via Bluetooth Smart using Android BluetoothGatt. The data contains values for temperature, pressure and humidity. The values are splitted up in the following way.
PRESSURE:
Byte 1 + Byte 2 + first 4 Bits of Byte 3, other 4 bits are 0
TEMPERATURE:
Byte 4 + Byte 5 + first 4 bits of Byte 6, other 4 bits are 0
HUMIDITY:
Byte 7 + Byte 8
Now at the moment I have a Byte Array that contains the 8 Byte.
My Problem is that I don't know how to extract or isolate the bits for temperature, pressure and humidity as described above.
Does anyone have an idea how to solve this?
You need to use bit manipulation operations to extract the values.
For example
int pressure = (byte[0]&0xff)<<16+(byte[1]&0xff)<<8+(byte[2]&0xff)
(the 16s and 8s may need to be 12 and 4 or 0 4 and 12 depending on exactly what it means).
The operations you need are << which shifts the bits inside the byte around and the &0xff which changes the signed byte into a signed integer before you shift it. Otherwise the sign bit will mess things up.
Related
I am learning how MIDI works and am wondering how to merge two bytes. There is a paragraph that states the following
“The status and channel Bytes are merged into one byte (00-FF) Because these messages have an MSB (Most Significant Byte) of 1 the command statuses actually begin at 80 hexadecimal (128 and up to 255) The LSB (Least Significant Byte takes a value of 0-F Hexadecimal (0 to 15) to specify which MIDI channel the command will be sent to. A command message tells the MIDI gear to perform certain types of things like play a note, change the volume, add effects, and other types of things. This table shows the different command status and what they do.”
I am not 100% sure what it means by merging Bytes into a byte. Any help would be appreciated. If you could provide an example of how to do this in java with an explanation I’d be even more grateful.
So I found the answer to the problem.
Byte b1 = 0xF;
Byte b2 = 0xF;
Byte merged = (b1 >> 4 | b2);
Byte 1 is shifted four bits to the left to guarantee it is the most significant bit while byte 2 is bitwise or as the least significant bits. The important thing is that the paragraph i posted above says you may merge two bytes together. Both bytes must be at a maximum of 4 bits. If they exceed 8 bits total the result is a short or int based on how large the result is.
I have an array of 9 bytes in Java but my function need to return an array of size 10. The difference I need to pad with Nibbles.
If a nibble is a half of a byte, can I simply add a (byte) 0 to an array at the end or adding 2 nibbles instead will make a difference? Is there a difference between 2 nibbles and a (byte) 0 in this case?
If a nibble is a half of a byte, can I simply add a (byte) 0 to an
array at the end or adding 2 nibbles instead will make a difference?
Is there a difference between 2 nibbles and a (byte) 0 in this case?
No there is no difference since a byte (8 bits) is made up 2 x nibble (4 bits).
Can I even put 8.5 bits into an array of bytes and then check the
array for "length" and get back 8.5 as value?
For 8.5 bits? At this point it will be returned as length of 2 bytes. If you mean 8.5 bytes then it's returned as 9 bytes.
Remember The smallest data-type is a byte not a nibble!! By declaring a type byte (even with no value assigned) you've automatically made 8 bits of 0000 0000. Nibbles just make it easier to visualize the bits within a byte's value (when written in hex notation).
For example the single byte value 0xF0 can be visualised as two nibbles of 1111 0000. Now for a byte 0xBA, if you wanted just one nibble you'll have to make the byte as either 0x0B or 0x0A...
I have an array of 9 bytes in Java but my function need to return an
array of size 10. The difference I need to pad with Nibbles.
Your function returns 80 bits. With 9 bytes you'll have a total 72 bits so you pad with extra 8 bits which means add one byte extra of zero value (eg: 0x00).
In the case of some 8 & half bytes, you should actually create 9 bytes (72bits) but only update the first 68 bits (8.5 bytes).
Best logic is to just declare a byte array with length of 10 (ie: 80 zero bits). Then you can update as many or as few bits as you need within this total allocated space. This way "I have an array of 9 bytes" becomes "I create an array of 10 bytes and only update 9 or even 8.5 bytes" which leaves you with automatic padding of those unused 1 or 1.5 bytes.
So your question is if nibble 0000 adjacent to nibble 0000 equals byte 00000000 ?
Yes.
When you write down the individual bits like that it should be obvious I think.
The need for padding with partial bytes will only arise when you are storing data with partial bytes. For example, let's assume I limited my character set to only a-z, A-Z, 0-9, and the space character. That would enable me to use only 4 bits to encode each character.
I'm trying to play an array in a Java program.
So far I was able to play byte arrays with the following code:
AudioFormat audioFormat = new AudioFormat(samplingFreq, bps, 1, true, true);
SourceDataLine sdline = AudioSystem.getSourceDataLine(audioFormat);
line.open(audioFormat);
sdline.start();
sdline.write(playArray, 0, playArray.length);
sdline.drain();
sdline.close();
However, with this I'm only able to play byte arrays since the write method only accepts byte arrays as argument. I want to be able to play 16/32 bits per sample arrays as well.
Are there any ways to play integer arrays or even doubles using AudioSystem(or any other class).
With the help of the comment from #greg-449, I was able to solve the problem. To play higher bits per second, you just need to increase the bps argument and send bytes one after another.
As an example, if we want to send 1867 as a sample, we need 16 bits which are as follows :
0000 0111 0100 1011
The first 8 bits are 7 in decimal and the second eight bits are 75 in decimal, so since we're using big endian(last argument of the AudioFormat argument), the first element of our byte array should be 7 and the second element should be 75. So for 16 bits, we just need two bytes for each sample.
I'm new to low level operations like this, I'm hoping someone can point out the obvious mistake I must be making here.
//Input value - 00111100
//I want to get the value of the bits at indexes 1-3 i.e 0111.
byte mask = (byte)0x00001111; // This gives 17 not the 15 I'd expect
byte shifted = (byte)(headerByte >> 3);
//shifted is 7 as expected
byte frameSizeValue = (byte)(shifted & mask); //Gives 1 not 7
It looks like the problem lies with the way the mask is defined, but I can't see how to fix it.
First of all 0x00001111 is in hex, which is a larger number than 255 - 16^3 + 16^2 + 16 + 1 = 4369 and byte overflows. Look here how to represent binary numbers or just use shifted & 15.
Your mask needs to be binary 00001111, which is equal to hex 0x0F.
byte mask = (byte)0x0F;
With java 7 you can create binary literals
byte binaryLit = (byte)0b00001111;
0xsomenumbers is a hex literal, and pre java7 there is no support for binaries.
You say you want to mask the first three bits but as Petar says, 0x001111 are not bits. If you want to mask the three bits you need to mask with 7
I have a spec which reads the column specifies a 16 bit offset to a structure and another column specifies a 24 bit offset to a structure. I am implementing the spec using java.
I am not clear of what 16 bit offset /24 bit offset means and how to perform such operation in java.
It sounds like you have single piece of data that is segmented into bit series.
Bits 16-23 are the "16 bit offset"
Bits 24-? are the "24 bit offset"
The data is probably a int (32-bit signed integer) or a long (64-bit signed integer) with certain parts of the bit sequence allocated to storing separate smaller pieces of data.
One way to simply get at the values is to use a bit mask and right shift, like this:
int mask = 0xf00; // only bits 16-23 are 1
int data;
int value = data & mask; // zero other bits
value >>= 16; // shift the value down to the end
An offset is a relative address in some stream and/or storage medium.
A 16bit offset is an offset that's stored in a 16 bit variable/slot.
So if some file format specification says that "the next field is the 16 bit offset" that means you must read the next 2 byte and treat it as a relative address.
What exactly that addresses depends on the specification: it might be bytes, it might be "entries" or anything else.
Note also, that Java doesn't have any built-in 24 bit data types, so you'll have to work around that using int, which has 32 bit.
It probably means the boundary of the data starts 16 bits or 24 bits after the start of that structure.
How you access it depends on how you got access to the structure to begin with.
If it's just something you read into a byte array, some data stored offset 16 bits could be accessed by ignoring the first two elements of the array (2 byte = 8 bits * 2), or 3 for 24 bits. If it's an long or an int, it depends if you can use the >> and << shift operators.