Converting C defined data types (None Specified)
At 14 JUL 1999 05:47:04AM Peter Richards wrote:
Hi,
Can someone please explain how to convert any "C" defined data types in OpenInsight. In particular data types:
DWORD/low word
DWORD/high word
DWORD/unsigned binary number
Also, I am not understanding how OI is evaulating the following, stored in a DWORD, and represents the chunk (audio data) size.
Apparently a "C" DWORD is 4 bytes, and when viewed in debug, the HEX value is 5A030000, and after removing the "C trailing binary zeros", the correct hex value is 5A03, which is:
0101 1010 0000 0011 binary23043 decimalWhen I run OI with Test_hex=IConv("5A03","MX") the value is correct, 23043, however if a variable called Bext_chunk_size=\5A03\, then why does Bext_size=IConv(Bext_chunk_size,"MX") return the incorrect result (can't remember, but it was either zero or null) ?
Any assistance with understanding how to convert these C data types would be appreciated.
Thanks,
Peter
At 14 JUL 1999 07:47AM Cameron Purdy wrote:
Hi Peter,
If you have the OpenInsight programmers reference manual, see the chapter (I believe it is chapter 7) about calling DLLs. There is some helpful and relevant information there. Also see the STRUCT related entries, such as Var_To_Struct and Struct_To_Var.
Cameron Purdy
Revelation Software
At 14 JUL 1999 09:18AM Carl Pates - Sprezzatura Group wrote:
Peter
When I run OI with Test_hex=IConv("5A03","MX") the value is correct, 23043, however if a variable called Bext_chunk_size=\5A03\, then why does Bext_size=IConv(Bext_chunk_size,"MX") return the incorrect result (can't remember, but it was either zero or null) ?
\5A03\ is not a number in Basic+ !! It represents the HEX codes for the ASCII characters 5A and 03 and is equivalent to saying:
Bext_chunk_size=Char(90) : Char(3)
That's why your IConv won't work.
Carl Pates
Sprezzatura Group
(and still having fun with French keyboards
![]()
At 19 JUL 1999 06:12AM Peter Richards wrote:
Hi Cameron,
The file I am reading in OI is a .WAV file and it follows the RIFF standard by Microsoft, therefore the C data types. I need to change some of the header info for radio broadcasting and am using OI to read the .WAV as a 'flat' file.
] …., see the chapter (I believe it is chapter 7) about calling
] DLLs. There is some helpful and relevant information there.
] Also see the STRUCT related entries, such as Var_To_Struct and ] Struct_To_Var.
I tried using the 'struct' commands, but no doubt they are only for DLL use. Here's an example of what the data looks like under a HEXVIEW program, positions 25 to 28 are 44 AC 00 00 (hex).
The code I had to use was the following:
Convert_to_Dec:
Swap_Bytes='Temp=data start, lengthFor a=length to 1 step -1If Tempa,1=\00\ thenend elseSwap_Bytes=Swap_Bytes:Tempa,1endNext aConv_to_Hex=Oconv(Swap_Bytes,"HEX")Hex_to_Dec=Iconv(Conv_to_Hex,"MX")Return
This returned the var 'Hex_to_Dec'= 176400, which is the correct value from the .WAV file. Those 'trailing binary zeros' appear to be a trademark of data types used by C
Is there an easier way ? The process of reading these headers is split up into different chunks of data, and then all the data is by position. The data types on a record spec state either WORD or DWORD for the C data types, but Chapter 7 of the OI prog ref manual doesn't specify these. Do they correspond to another data type ?
Thanks,
Peter
At 19 JUL 1999 07:54AM Cameron Purdy wrote:
Peter,
I tried using the 'struct' commands, but no doubt they are only for DLL use.
That is not correct. They are useful any time you have packed binary types, like the example you describe.
Here's an example of what the data looks like under a HEXVIEW program, positions 25 to 28 are 44 AC 00 00 (hex).
That is a DWORD, right? A DWORD is a 4-byte value, otherwise known as a long. Since this is x86, the little endian notation reverses the bytes, so the value is actually 0x0000AC44.
Those 'trailing binary zeros' appear to be a trademark of data types used by C
Nope, it is the x86 processor that likes them that way. The value is a fixed length (4 bytes) but by using little endian it can be cast to a one or two byte value simply by only looking at the first byte or two because the least significant bytes come first. (There are probably other reasons why Intel chose little endian, but I don't know them.)
Is there an easier way?
Yes, use the struct functions.
The process of reading these headers is split up into different chunks of data, and then all the data is by position. The data types on a record spec state either WORD or DWORD for the C data types, but Chapter 7 of the OI prog ref manual doesn't specify these. Do they correspond to another data type ?
Yes, a WORD is a 2-byte int and a DWORD is a 4-byte int. I believe that both are declared as unsigned, but in OpenInsight you cannot use 4-byte unsigned values, so use a 4-byte signed value.
Cameron Purdy
Revelation Software
At 21 JUL 1999 02:54AM Peter Richards wrote:
Hi Cameron,
Thanks for the tips on using these data types; sure is easier with the Struct_To_Var command. Now there is one minor problem. I have used the Define_Struct form to add the following struct called WAV_CHUNK (I need to be able to read data chunks from .WAV files)
Type Offset Size
char4 0 4
signed LONG 4 4
char4 8 4
char4 12 4
signed LONG 16 4 value=52 in this example
char52 20 52 char4 72 4 signed LONG 76 4 value=12 char12 80 12
char4 92 4
signed LONG 96 4 value=14
char14 100 14 char4 114 4 etc, etc Using the Struct_To_Var is great for the other data chunks, because they are fixed length, however this chunk is variable length. The netries marked are the variable length fields; the length is stored in the previous data item (signed LONG) in each case.
Is the only row defined in SYSREPOS for this struct Appname*APPROW**SYSOBJ:STRUCT_WAV_CHUNK ? I got a 'too many keys, truncating' when trying to look in SYSREPOS. The data in the row retrieved doesn't reflect the values added via Define_Struct form.
There is a row in SYSOBJ called SYSOBJ*SRUCT_WAV_CHUNK with:
Total size in bytes
Number of elements
Type (mv) value 9=char; 4=signed long
Size
How do I change the values of the struct (*without* having to run the Define_Struct routine; this forces an event and runs a form)
programatically ?
Maybe there is another row in SYSREPOS that I couldn't see, or maybe I'm going about this the wrong way !!! :)
You can see that for every different .WAV file, the struct WAV_CHUNK needs to be modified, so that it can return the correct values, simply because this particular chunk is variable length.
Thanks,
Peter
At 21 JUL 1999 07:22AM Cameron Purdy wrote:
Peter,
Wow, that is quite an undertaking (to rip apart .WAV files yourself).
What I would do would be to define the fixed length structures with Define_Struct and just grab the variable length stuff with square bracket operators . Using Struct_Len, for example, you know how far to "walk" the data, so if you have a fixed length X followed by a variable length chunk followed by a fixed length Y:
Rec=…
* parse a fixed length portion
X=Struct_To_Var(Rec, "X")
Rec1,Struct_Len("X")="
* the length of the variable length portion is in the data we just parsed
Chunk=Rec1,X
Rec1,X="
* parse the next fixed length portion
Y=Struct_To_Var(Rec, "Y")
Rec1,Struct_Len("Y")="
…
Cameron Purdy
Revelation Software
At 21 JUL 1999 10:14PM Peter Richards wrote:
Hi Cameron,
Thanks for the tips on how to do that, it works just great !!! :)
Ran into a minor problem when adding some new structs via the Define_Struct form. I have added 4 new structs, but can only 'see' one of them in the combobox in form DEFINE_STRUCT.
Before this problem occured, I was able to add new structs okay, and also view them all in the combobox.
The only thing I did, that was different, was instead of creating a new sruct from scratch, and adding each data type manually, after the 'new/name' process, I selected the 'copy from' button, grabbed the definitions from another struct, and then pressed 'close'. On the std WIN, 'do you want to save', I decided not to keep it, and selected NO.
Now every new struct that is built via DEFINE_STRUCT does not appear in the combobox. However they do appear in the popup if I select 'Copy from' button. I have checked out the appropriate rows in SYSREPOS and SYSOBJ, comparing the values in the new struct I can view in the combobox to the ones I cannot view, and can see no obvious differences. Also, I checked the row in SYSOBJ called !STRUCT and everything (all the struct names, in order) is there.
Whilst I can access the 'hidden' structs via Struct_To_Var, etc, I cannot modify them at present. Here's the log from the engine:
This one
RUN RUN_EVENT 'SYSPROG*OIWIN', 'DEFINE_STRUCT.LB_NAME', 'COMBOBOX', 'LOSTFOCUS*2*SYSPROG*LOSTFOCUS..OIWIN*', '1','DEFINE_STRUCT.CB_COPY'
is returning all the structs, whilst
RUN RUN_EVENT 'SYSPROG*OIWIN', 'DEFINE_STRUCT.LB_NAME', 'COMBOBOX', 'GOTFOCUS*2*SYSPROG*GOTFOCUS..OIWIN*', 'DEFINE_STRUCT.LB_NAME'
doesn't. (Previously, everything appeared in the combobox). I have also checked that there are no LH errors with SYSOBJ and SYSREPOS, and rebuilt the system index. Any clues ??
Regards,
Peter
At 21 JUL 1999 10:53PM Peter Richards wrote:
Cameron,
Please ignore my previous post in this thread. The DEFINE_STRUCT works okay, and I can view all of them.
Swapping from developing apps using Clipper(DOS) to OI, I forgot that I need to use the up and down arrows to view other entries in the combobox (that's my excuse and I'm sticking to it).
I can almost hear you laughing from here !! :)
Thanks again for the tips on using structs; now one command can retrieve a complete block of data, as long as I have the offset and data type correct (fixed length block). The extra code you supplied, now I can read the variable length data as well.
Have you stopped laughing yet ?
Peter
At 22 JUL 1999 08:09AM Cameron Purdy wrote:
Hi Peter,
No loud guffaws here. I did grin though.
Glad you got it working.
Cameron Purdy
Revelation Software