converting 24bit samples to Int32

edited January 2015 in Software
I' asking a very basic question. The algorithm mentioned here :http://docs.openbci.com/software/02-OpenBCI_Streaming_Data_Format#openbci-v3-data-format-interpreting-the-eeg-data for the given method does this 



int interpret24bitAsInt32(byte[] byteArray) {
int newInt = (
((0xFF & byteArray[0]) << 16) |
((0xFF & byteArray[1]) << 8) |
(0xFF & byteArray[2])
);
if ((newInt & 0x00800000) > 0) {
newInt |= 0xFF000000;
} else {
newInt &= 0x00FFFFFF;
}
return newInt;
}
now 0xFF000000 is greater than what a signed 32 bit int can hold, which implies the int here is actually an unsigned 32 bit integer? Also in turn implying no negative values will be sent in the byte array as per the OpenBCI data format?

Comments

  • wjcroftwjcroft Mount Shasta, CA
    edited January 2015
    Dhruv, just consider the code as turning a 24 bit signed integer into a 32 bit signed integer. That is all it does.

    Both positive and negative 24 bit values are produced in the ADS1299 data stream.

    William

  • edited January 2015
    Ran a little test for the C# implementation.. sharing just in case.. 
    PS: this is a console application.

    ---

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace BitExperiments
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Test 16bit to Int32(MSB First/Left)
                Console.WriteLine("=======Test 24 bit to Int32 (MSB First/Left)=======");
                Dictionary<int,byte[]> cases = new Dictionary<int,byte[]>();
                byte[] bytearr;
                int expectedResult;

                bytearr = new byte[] { 0x7F, 0xFF, 0xFF };
                expectedResult= 8388607;//Max
                cases.Add(expectedResult,bytearr);

                bytearr = new byte[] { 0xFF, 0xFF, 0xFF };
                expectedResult = (-1);//Mid
                cases.Add(expectedResult,bytearr);

                bytearr = new byte[] { 0x80, 0x00, 0x01 };
                expectedResult = (-8388607);//Min
                cases.Add(expectedResult,bytearr);

                bytearr = new byte[] { 0x5D, 0xCB, 0xED };
                expectedResult= 6147053;//Random
                cases.Add(expectedResult,bytearr);

                bytearr = new byte[] { 0xA2, 0x34, 0x13 };
                expectedResult= (-6147053);//Random  inverted
                cases.Add(expectedResult,bytearr);

                foreach (var value in cases)
                {
                    Console.WriteLine("Expected: {0} \t\t Bit24ToInt32 Test:  {1}", value.Key, Bit24ToInt32(value.Value));
                }
               
                Console.WriteLine("===================================================");
                Console.WriteLine();
                //Test 16bit to Int32(MSB First/Left)
                Console.WriteLine("=======Test 16 bit to Int32 (MSB First/Left)=======");
                cases.Clear();

                bytearr = new byte[] { 0x7F, 0xFF };
                expectedResult = 32767;//Max
                cases.Add(expectedResult, bytearr);

                bytearr = new byte[] { 0xFF, 0xFF };
                expectedResult = (-1);//Mid
                cases.Add(expectedResult, bytearr);

                bytearr = new byte[] { 0x80, 0x01 };
                expectedResult = (-32767);//Min
                cases.Add(expectedResult, bytearr);

                bytearr = new byte[] { 0x5D, 0xED };
                expectedResult = 24045;//Random
                cases.Add(expectedResult, bytearr);

                bytearr = new byte[] { 0xA2, 0x13 };
                expectedResult = (-24045);//Random  inverted
                cases.Add(expectedResult, bytearr);

                foreach (var value in cases)
                {
                    Console.WriteLine("Expected: {0} \t\t Bit16ToInt32 Test:  {1}", value.Key, Bit16ToInt32(value.Value));
                }
                Console.WriteLine("===================================================");
                Console.ReadLine();
            }
            private static int Bit24ToInt32(byte[] byteArray)
            {
                int result = ( 
                     ((0xFF & byteArray[0]) << 16) | 
                     ((0xFF & byteArray[1]) << 8) |  
                     (0xFF & byteArray[2]) 
                   ); 
                 if ((result & 0x00800000) > 0)
                 { 
                   result = (int)((uint)result|(uint)0xFF000000); 
                 }
                 else
                 { 
                   result = (int)((uint)result & (uint)0x00FFFFFF); 
                 } 
                return result;
            }
           
            private static int Bit16ToInt32(byte[] byteArray) {
                int result = (
                  ((0xFF & byteArray[0]) << 8) |
                   (0xFF & byteArray[1])
                  );
                if ((result & 0x00008000) > 0) {
                      result = (int) ((uint) result | (uint) 0xFFFF0000);

                } else {
                      result = (int) ((uint) result & (uint) 0x0000FFFF);
                }
                return result;
              }        
        }
    }



  • Output:

    =======Test 24 bit to Int32 (MSB First/Left)=======
    Expected: 8388607                Bit24ToInt32 Test:  8388607
    Expected: -1             Bit24ToInt32 Test:  -1
    Expected: -8388607               Bit24ToInt32 Test:  -8388607
    Expected: 6147053                Bit24ToInt32 Test:  6147053
    Expected: -6147053               Bit24ToInt32 Test:  -6147053
    ===================================================

    =======Test 16 bit to Int32 (MSB First/Left)=======
    Expected: 32767                  Bit16ToInt32 Test:  32767
    Expected: -1             Bit16ToInt32 Test:  -1
    Expected: -32767                 Bit16ToInt32 Test:  -32767
    Expected: 24045                  Bit16ToInt32 Test:  24045
    Expected: -24045                 Bit16ToInt32 Test:  -24045
    ===================================================

  • biomurphbiomurph Brooklyn, NY
    dhruv, so it works?


    the ADS outputs 24bit signed in 2's compliment
    When I convert to 32bit, I merely retain the sign of the number by ether setting the high byte to FF or 00.
  • edited January 2015
    @biomurph, Yes indeed it works, the algo you have is correct, however c# gave me a syntax error when i tried to  fit FF000000 in a signed integer, and hence i tweaked the algo a little, to treat the self | and self & as an unsigned operation.
    "the ADS outputs 24bit signed in 2's compliment"
    I understood this part after I had to looked into the bits, but thanks for confirming.

    Also I made a typo in a comment //Test 16bit to Int32(MSB First/Left) it should say 24 instead of 16. Please ignore
  • hiranhiran Singapore
    uint32 rVal = 0xF12343; //24Bit value
    int32_t adcValue32 = rVal & 0x800000 ? 0xff000000 | rVal rVal;
Sign In or Register to comment.