Thread: Encoding data in 7 bit words, need some ideas.

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485

    Encoding data in 7 bit words, need some ideas.

    I need to repackage data to be sent in 7 bit words with the MSB padded. I have tried different approaches but the last byte comes out wrong. The 16 bit value 0x87E5 would be encoded into three bytes like this:

    original.

    10000111 11100101

    encoded.

    01000011 01111001 00100000

    I have been trying to do it like this but the third byte comes out wrong. This is what I have tried so far, there might be better / more clever way of achiving the same thing though. Interested to hear your input on this.

    // 1.) ........10000111 11100101 00000000
    // 2.) ...>> 01000011 11110010 10000000
    // 3.) .................>> 01111001 01000000
    // 4.) ...............................>> 00100000

    Code:
    	unsigned char byte[4] = {0};
    	int large = 0x87E5;  		          // 10000111 11100101 00000000 00000000
    	large >>= 1;				  // 01000011 11110010 10000000 00000000
    	printf("%x\n", large);
    	large = htons(large);		 
    	memcpy(&byte, &large, 3);	  
    	binary(byte[0]);			  // 01000011 >OK
    	
    	byte[1] >>= 1;
    	binary(byte[1]);			  // 01111001 >OK
    	
    
    	large >>= 1;
    	memcpy(&byte[2], &large, 3);
    	byte[4] >>= 1;
    	binary(byte[4]);			  // 01111111 >wrong! should be 00100000?
    BTW, the call to the binary() function prints in binary to stdout, thanks Dino for the hint on how to do this.
    Last edited by Subsonics; 01-18-2009 at 08:58 AM.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I'm not following how you get from the original to the encoded.
    Code:
    original.
    10000111 11100101
    encoded.
    01000011 01111001 00100000
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    And, I haven't looked in detail, but I don't think your assumption on how this works is correct.
    Code:
    int large = 0x87E5;  		          // 10000111 11100101 00000000 00000000
    large >>= 1;				  // 01000011 11110010 10000000 00000000
    I suspect the end result would be
    Code:
    large >>= 1;				  // 01000011 11110010 00000000 00000000
    As you are shifting an integer, not a character. Shifting an integer one bit to the right has the effect of dividing by 2, regardless of how the int is stored in memory (big or little endian).
    Mainframe assembler programmer by trade. C coder when I can.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Dino View Post
    And, I haven't looked in detail, but I don't think your assumption on how this works is correct.
    Code:
    large >>= 1;				  // 01000011 11110010 00000000 00000000
    That might well be true, that might be an explaination of why the last byte comes out wrong.

    Quote Originally Posted by Dino View Post
    As you are shifting an integer, not a character. Shifting an integer one bit to the right has the effect of dividing by 2, regardless of how the int is stored in memory (big or little endian).
    At first I tried to shift the individual chars of the array, but doing a right shift in byte[0] makes the LSB dissapear, what I want is to have it pushed into the MSB of array[1] and the last bit of that into array[2], but it turned out not to work that way. That´s why I tried to make the bitwise shift on the integer first before I copied to the array.
    Last edited by Subsonics; 01-18-2009 at 09:23 AM.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Dino View Post
    I'm not following how you get from the original to the encoded.
    Code:
    original.
    10000111 11100101
    encoded.
    01000011 01111001 00100000
    I´m not, the above is what the result should look like when done correctly.

    encoded.
    01000011 01111001 00100000

    The reds are a one bit pad, but to store the original 16bit value three bytes are needed.

    What I´m getting is this:

    01000011 01111001 01111111
    Last edited by Subsonics; 01-18-2009 at 09:30 AM.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    I added a "binary(large);" efter the bitwise shift in the integer and it does indeed show that the last bit gets lost. I need a different approach I suppose.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, you have one 16-bit word, and you want to store it as 3 8-bit words in preparation to send them down some link that only accepts seven-bit words, am I correct? [Or you are told to do this for your school project, because it is a useful excercise].

    My approach would be to take the 7 top bits by copying the original data into another 16-bit variable, then shifting 9 bits down. Then take the remaining 16 bits and shift down 2 bits and mask off the unwanted top bits using an "and" operation. Finally, take the bottom 2 bits and put them in the third word.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by matsp View Post
    So, you have one 16-bit word, and you want to store it as 3 8-bit words in preparation to send them down some link that only accepts seven-bit words, am I correct?
    Yes, thats correct. I´m using it to transmit MIDI which is value 0-127 only. Normally one package is all it takes to send a message, but I´m trying to send sampled sound data to a sampler according to SDS standard (for midi sample dump) so it´s 16 bit words in this case that needs to be re-packaged according to the MIDI standard.

    Quote Originally Posted by matsp View Post
    My approach would be to take the 7 top bits by copying the original data into another 16-bit variable, then shifting 9 bits down. Then take the remaining 16 bits and shift down 2 bits and mask off the unwanted top bits using an "and" operation. Finally, take the bottom 2 bits and put them in the third word.

    --
    Mats
    That seems like it would work, I´ll have a go at it. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [question]Analyzing data in a two-dimensional array
    By burbose in forum C Programming
    Replies: 2
    Last Post: 06-13-2005, 07:31 AM
  2. Binary Tree, couple questions
    By scoobasean in forum C Programming
    Replies: 3
    Last Post: 03-12-2005, 09:09 PM
  3. bit patterns of negtive numbers?
    By chunlee in forum C Programming
    Replies: 4
    Last Post: 11-08-2004, 08:20 AM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM