473,320 Members | 1,861 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

24 bit words

Thanks for the comments on my last post, they were very useful. Here is another
question that it would be useful to get some comments on. I deal a lot with
sound data which comes in a fixed format of either signed 16 or 24 bit
integers. What is the best way of defining these types to allow some level
of portability? Is it simply a matter of using conditional preprocessor
inclusions to create a type suitable for a particular machine? Such as:

#ifdef SUN
typedef word16_t short;
#else
.... define for other platforms.

Also, for converting 24 bit integers to 32 bit (so I can use them) I have
written this:
#define WORD24_LEN 3

typedef long s32word_t; /* OK for Max OS X/G5 but not nesc. other platforms */

union word32 {
s32word_t lword;
unsigned char byte[4];
};

s32word_t word24toword32(const char *pWord24) {

union word32 outputword;
register unsigned int i;

for(i=0;i<WORD24_LEN;i++) outputword.byte[i+1] = pWord24[i];

if (outputword.byte[1] >= 0x80) outputword.byte[0] = 0xff;
else outputword.byte[0] = 0x00;

return(outputword.lword);

}

void word32toword24(s32word_t inword, char *pWord24) {

union word32 inputword;
register unsigned int i;

inputword.lword = inword;
for(i=0;i<WORD24_LEN;i++) pWord24[i] = inputword.byte[i+1];

}
I am wondering if there is a nicer way to do this?

Robert
Jul 10 '06 #1
9 5925
Robert Dow wrote:
Thanks for the comments on my last post, they were very useful. Here is another
question that it would be useful to get some comments on. I deal a lot with
sound data which comes in a fixed format of either signed 16 or 24 bit
integers. What is the best way of defining these types to allow some level
of portability? Is it simply a matter of using conditional preprocessor
inclusions to create a type suitable for a particular machine? Such as:
<snip unions>

No. Load the bytes by shifting and ORing. That's the portable way.

Does your device actually send 24 bit words though? I'd think most
would just pack them in a 32-bit word for shipping over the bus.

Tom

Jul 10 '06 #2
Tom St Denis <to********@gmail.comwrote:
Does your device actually send 24 bit words though? I'd think most
would just pack them in a 32-bit word for shipping over the bus.

Tom
I should have mentioned that the data comes from files and is in the format of
24 bit words.

Robert
Jul 10 '06 #3
Robert Dow wrote:
Thanks for the comments on my last post, they were very useful. Here is another
question that it would be useful to get some comments on. I deal a lot with
sound data which comes in a fixed format of either signed 16 or 24 bit
integers. What is the best way of defining these types to allow some level
of portability? Is it simply a matter of using conditional preprocessor
inclusions to create a type suitable for a particular machine? Such as:

#ifdef SUN
typedef word16_t short;
#else
... define for other platforms.
On every C99 platform where there is a 16 bit data type available,
there's int16_t in inttypes.h, you don't have to recreate it yourself.

Philipp
Jul 10 '06 #4
In article <e8**********@scotsman.ed.ac.uk>
Robert Dow <rj*@music.ed.ac.ukwrote:
>... I deal a lot with sound data which comes in a fixed format
of either signed 16 or 24 bit integers. What is the best way of
defining these types to allow some level of portability?
First, you need to decide "how much portability", because:

- most machines today have signed, 16-bit, two's complement "short",
so you can just use that for the first;

- any system that supports "enough" C99 will also have <inttypes.h>
which will define the type "int16_t" for you; and

- it is possible to do all your 16-bit work with "unsigned short"
(which is guaranteed to be at least 16 bits) or plain (signed)
long in such a way that it is 100% portable, i.e., will work on
*any* conforming C implementation, even if it has ones' complement
signed arithmetic and/or 18- or 64-bit "short" -- but it will
take more work.

Having made such a decision...
>Also, for converting 24 bit integers to 32 bit (so I can use them) I have
written this:

#define WORD24_LEN 3

typedef long s32word_t; /* OK for Max OS X/G5 but not nesc. other platforms */

union word32 {
s32word_t lword;
unsigned char byte[4];
};
(and complicated code to manipulate them)

The phrases that come to mind here are "ew" and "don't do that". :-)

Given 3 8-bit octets that should from a "FILE *fp", do this -- note
that you can do the obvious thing if these octet-bytes are already
in an array of "unsigned char":

unsigned long accum;
long val;
unsigned char c[3];

/* fread takes (base, width, nelements, FILE *) */
if (fread(c, 1, 3, fp) != 3) ... handle error ...

#if UCHAR_MAX != 255 /* this #if is optional */
/*
* This step is optional, and a no-op if UCHAR_MAX is 255 as usual;
* or you could inspect the values to see if they are out of range,
* which implies something went wrong in reading 8-bit octets on
* your 9- or 18- or 24-bit "unsigned char" machine.
*
* Note that a good C compiler should generate no code here even
* without the "#if" above, in the usual (UCHAR_MAX == 255) case.
*/
c[0] &= 0xff;
c[1] &= 0xff;
c[2] &= 0xff;
#endif

/* here is where you decide on File Byte Order */
accum = (unsigned long)c[0] << 16; /* if c0 is the topmost bits */
accum |= (unsigned)c[1] << 8;
accum |= c[2];

#define SIGNBIT (1UL << 23)
/* now convert unsigned 24-bit value to signed 32-bit value */
val = (long)(accum ^ SIGNBIT) - (long)SIGNBIT;

Note that this code can be adapted to force the correct interpretation
of any bit-length word up to 31, or in C99, 63 using "long long".
This code works even if the target machine has 72-bit "int" or uses
ones' complement, because it operates strictly on the *values*
in the 24-bit field.

You can see how this works if we make a table for a 3-bit two's
complement number, which can go from -4 to +3:

desired value (as unsigned) value after
"sign" bit1 bit0 value after flipping "sign" subtracting 4
------ ---- ---- ---- --------------------- -------------
0 0 0 0 4 0
0 0 1 1 5 1
0 1 0 2 6 2
0 1 1 3 7 3

1 0 0 -4 0 -4
1 0 1 -3 1 -3
1 1 0 -2 2 -2
1 1 1 -1 3 -1

The only gimmick here is that the intermediate and final signed
values (after flipping the top bit and converting to the signed
variant) have to fit within LONG_MIN..LONG_MAX. Since these are
guaranteed to be at least -2147483647..+2147483647, we can certainly
go to 31 bits, which needs only a range of -1073741824..+1073741823.
(Going to 32 fails if LONG_MIN is -2147483647 instead of -2147483648,
but otherwise actually still works.)

To convert back, use the obvious corresponding technique (add bias
with native signed arithmetic, convert to "unsigned long", and flip
top bit).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 10 '06 #5
On Mon, 10 Jul 2006 18:50:01 +0000, Chris Torek wrote:
- any system that supports "enough" C99 will also have <inttypes.h>
which will define the type "int16_t" for you; and
Chris would have intended to write <stdint.habove. Though I'm glad to
discover the <inttypes.h("Format conversion of integer types") header.
It will assist in the portable printing and scanning of fixed integer
types.

Regards,
Adam
Jul 11 '06 #6
jjf

Adam Warner wrote:
On Mon, 10 Jul 2006 18:50:01 +0000, Chris Torek wrote:
- any system that supports "enough" C99 will also have <inttypes.h>
which will define the type "int16_t" for you; and

Chris would have intended to write <stdint.habove. Though I'm glad to
discover the <inttypes.h("Format conversion of integer types") header.
It will assist in the portable printing and scanning of fixed integer
types.
Brave assumption. <inttypes.hincludes <stdint.h>. Chris may choose to
always use the former when he needs the specified width types, to make
sure that the gubbins to do I/O on them is always to hand.

Jul 11 '06 #7
In article <pa****************************@consulting.net.n z>
Adam Warner <us****@consulting.net.nzwrote:
>On Mon, 10 Jul 2006 18:50:01 +0000, Chris Torek wrote:
> - any system that supports "enough" C99 will also have <inttypes.h>
which will define the type "int16_t" for you; and

Chris would have intended to write <stdint.habove.
Indeed -- although my C99 text-only draft is sufficiently old that it
says inttypes.h instead of stdint.h (everywhere). Since this was
<inttypes.hat various points during C99 development, it is possible
there are systems that have <inttypes.hand not <stdint.h>, too.

(I would be more tempted to buy a "proper" C99 PDF if PDF files were
grep-able, etc. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 11 '06 #8
On Tue, 11 Jul 2006 05:54:28 +0000, Chris Torek wrote:
In article <pa****************************@consulting.net.n z>
Adam Warner <us****@consulting.net.nzwrote:
>>On Mon, 10 Jul 2006 18:50:01 +0000, Chris Torek wrote:
>> - any system that supports "enough" C99 will also have <inttypes.h>
which will define the type "int16_t" for you; and

Chris would have intended to write <stdint.habove.

Indeed -- although my C99 text-only draft is sufficiently old that it
says inttypes.h instead of stdint.h (everywhere). Since this was
<inttypes.hat various points during C99 development, it is possible
there are systems that have <inttypes.hand not <stdint.h>, too.

(I would be more tempted to buy a "proper" C99 PDF if PDF files were
grep-able, etc. :-) )
I'm a tad ashamed that the reference I consulted was the headers in
/usr/include/* from Debian sid's GNU libc 2.3.6:
$ dpkg -S /usr/include/stdint.h
libc6-dev: /usr/include/stdint.h
<http://packages.debian.org/changelogs/pool/main/g/glibc/glibc_2.3.6-15/changelog>

...

/*
* ISO C99: 7.18 Integer types <stdint.h>
*/

...

/* Exact integral types. */

/* Signed. */

/* There is some amount of overlap with <sys/types.has known by inet code */
#ifndef __int8_t_defined
# define __int8_t_defined
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
...

Platform specific and certainly not authoritative, but grep-able :-)

I am familiar with GNU C's C99 compatibility caveats:
<http://gcc.gnu.org/c99status.html>

Regards,
Adam
Jul 11 '06 #9
Thank you all for your advice.

Robert
Jul 11 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: superprad | last post by:
"X-No-Archive: yes" what I am looking for is 1. To create a list of different words of various lengths(1-15) using A-Z,a-z,0-9 and punctuations.Basically anything that could be found on a...
2
by: CV | last post by:
How can I match 'n' number of neighbouring words of a pattern using regular expressions? For example, suppose I am looking for the pattern "length xyz cm" in some text. where xyz is a number -...
8
by: Rick | last post by:
I have a program that reads from a file. In the file are a series of words. I read in all the words into a string array, find the average length, count the number of words, display the longest...
7
by: Sling | last post by:
I code in Rexx on the mainframe which has 2 built-in functions: word(s,i) & words(s). word(s,i) returns the ith word in the s(tring), and words(s) returns the number of words within the s(tring)....
7
by: Jim Carlock | last post by:
Looking for suggestions on how to handle bad words that might get passed in through $_GET variables. My first thoughts included using str_replace() to strip out such content, but then one ends...
7
by: abraxas | last post by:
Ok maybe someone here can help me. I have been learning c++ and have been toying with some basic programming and have run into something that I would have assumed would have been fairly easy. I...
7
by: Jay | last post by:
How would I be able to grab random words from an internet source. I'd like to grab a random word from a comprehensive internet dictionary. What would be the best source and the best way to go...
20
by: dmurray14 | last post by:
Hey guys, I'm a C++ newbie here - I've messed with VB, but I mostly stick to web languages, so I find C++ to be very confusing at times. Basically, I am trying to import a text file, but I want...
6
by: Xernoth | last post by:
Hi, I have an exercise that requests the following: Write a function that reads words from an input stream and stores them in a vector. Use that function both to write programs that count the...
14
bugboy
by: bugboy | last post by:
I'm a beginner at this and am confused... I have three tables: 1. words / wordpk, word 2. definitions / definitionspk and definition 3. associations / wordpk, definitionspk 'words' holds...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.