Posts: 795
Threads: 136
Joined: Feb 2009
Hi Gintaras, hi all
Gintaras, i need some explanations on the LameWavToMp3 macro.
I understand that QM handles some C++ syntax differently, and I understand 90% of the QM code, but some are beyond my
understanding.
1. type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal
it's the translation of this
struct {
DWORD dwSampleRate;
BYTE byMode;
WORD wBitrate;
BYTE byEncodingMethod;
} aac;
why WORD wBitrate is converted to [+1]@wBitrate and not simply @wBitrate? i think it's an offset stuff but can't get it.
2. type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac
i understand that it's QM translation for an union , but why use it? offset again?
____BE_CONFIG11'mp3
[]____BE_CONFIG12'LHV1
[]____BE_CONFIG13'aac
i speak about [] before variable names....why mandatory in QM and not used in C?
3. can you explain this conversion?
typedef void* HBE_STREAM;
typedef HBE_STREAM *PHBE_STREAM;
typedef unsigned long BE_ERR;
QM:
type BE_ERR = #
type HBE_STREAM = #
Thanks!
Posts: 12,092
Threads: 142
Joined: Dec 2002
1. Yes, offset 1 from byMode. Without it would be offset 2. The C header file contains this:
#pragma pack 1
Or can be this, it works like C #pragma pack 1:
type ____BE_CONFIG11 dwSampleRate !byMode @wBitrate bPrivate bCRC bCopyright bOriginal [pack1]
2. In QM, nonstandard member offsets must be explicitly specified. Including union members. Like in C#. In C/C++ for it are used keyword union and directive #pragma pack.
More info in QM help topic "Type member alignment; unions".
3. Code "type TYPE = #" in a ref file means "there is no conversion of TYPE to QM; in QM use int instead of TYPE". Here # is int type character.
BE_ERR is unsigned long. QM does not have unsigned int.
HBE_STREAM is void*. Here void* is used to define a handle. In QM could be used byte*, but easier is to use int for handles. Like we use int for window handles, although in C it is a pointer typedef.
Posts: 795
Threads: 136
Joined: Feb 2009
for question one, as it's a bit tough to comprehend
i copied the wrong structure, its actually
struct {
DWORD dwSampleRate; // 48000, 44100 and 32000 allowed
BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed
BOOL bPrivate;
BOOL bCRC;
BOOL bCopyright;
BOOL bOriginal;
} mp3;
so type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal
holds in bytes size:
4/1/2/1/1/1/1
so dwSampleRate has offset 0, bymode offset 4, wBitrate offset 5
pack 1 is used to set wBitrate to 6, so it is offset is divisible by it's size, 2.
is this correct?
is yes, is size of bymode 2 instead of 1 then by padding, and then strucuture size is 12 instead of 11 at the original declaration?
would it be possible to invert bymode and wBitrate to make it aligned correctly (1 byte should be always well aligned)
____BE_CONFIG11 dwSampleRate @wBitrate !byMode bPrivate bCRC bCopyright bOriginal
then we have in sizes
4/2/1/1/1/1/1 and no pragma required, as those variables don't seem to be in the exact order in the struct declaration, or i'm mistaken on that point.
will study other answers later...
Posts: 12,092
Threads: 142
Joined: Dec 2002
In C: #pragma pack 1 sets wBitrate offset = 5. Without it would be 6.
In QM: [pack1] or [+1] sets wBitrate offset = 5. Without it would be 6.
To see type size use out sizeof(TYPE).
To see member offset use out &x.member-&x.
>would it be possible to invert bymode and wBitrate
no.
Posts: 795
Threads: 136
Joined: Feb 2009
that's exactly where i'm lost, even with extensive researches.
Quote:wBitrate offset = 5. Without it would be 6.
i must then suppose that the compiler would align automagically bymode to 2 byte to fit alignment of WORD wBitrate and that the C headers use pragma to
force it to be it's "right" alignment (for memory saving i guess)?
as
DWORD dwSampleRate => size 4 bytes offset 0
BYTE byMode => size 1 byte offset 4
WORD wBitrate size 2 bytes, offset should be 5 not 6 (4+1)
i will play with sizeof(i 'm away from my laptop right now) later to understand.
Quote:>would it be possible to invert bymode and wBitrate
no.
why? the order of the variables does not seem to be important...
Posts: 12,092
Threads: 142
Joined: Dec 2002
If the order is not important, then also don't need special packing. I thought the type is used with a dll function.
When defining private types, I usually order members like you said, to avoid gaps. But actually it is useful only if the type is used in large arrays or in large stack or saved in files.
Posts: 795
Threads: 136
Joined: Feb 2009
Quote:If the order is not important, then also don't need special packing. I thought the type is used with a dll function.
yes, i missed that and now i understand why pragma is used, it's indeed a dll function in bladeenc.dll
So order IS important as the call of the procedure must match the headers one.....
------------------------------------------------------------------
playing with sizeof, using pragma it's 23, 24 without it.
so this way is explicit packing (you say what variable to pack)
type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal
and this one is implicit or automatic, the argument seems to do it automatically
type ____BE_CONFIG11 dwSampleRate !byMode @wBitrate bPrivate bCRC bCopyright bOriginal [pack1]
Is this statement correct?
but i wonder why so much hassle to gain one byte meory, and seems from my readings that it's less perfomant than odd numbers of bytes.
2.
Quote: In QM, nonstandard member offsets must be explicitly specified. Including union members. Like in C#. In C/C++ for it are used keyword union and directive #pragma pack.
type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac
the empty brackets do mean to use previous packing method then, correct? but they are not the same size....
or is it just a convention for QM to work correctly?
3. ok, just translation of type to QM which own less types than C...i put them on a paper for further reference
Posts: 12,092
Threads: 142
Joined: Dec 2002
>Is this statement correct?
both correct.
>the empty brackets do mean to use previous packing method
no, it is like I wrote in QM help topic "Type member alignment; unions".
Posts: 795
Threads: 136
Joined: Feb 2009
yes from documentation
Quote:Empty brackets means same offset as of previous member
so here two empty brackets, for 2nd and third structure of the union.
So what does it mean as none of the brackets contain any number?????
Quote:type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac
here offset of struct contained in __BE_CONFIG1 is sized
24 for mp3
328 for LHV1
8 for aac
we could have waited for
type __BE_CONFIG1 ____BE_CONFIG11'mp3 [24]____BE_CONFIG12'LHV1 [352]____BE_CONFIG13'aac
can you explain a bit more?
Posts: 12,092
Threads: 142
Joined: Dec 2002
All offsets are 0.
Macro Macro515
ref lame "lame_def"
lame.__BE_CONFIG1 x
out "%i %i %i %i %i %i %i" &x.mp3-&x &x.LHV1-&x &x.aac-&x sizeof(____BE_CONFIG11) sizeof(____BE_CONFIG12) sizeof(____BE_CONFIG13) sizeof(__BE_CONFIG1)
;0 0 0 24 328 8 328
Posts: 795
Threads: 136
Joined: Feb 2009
ok, so why is it useful then if all are 0?
only convention to translate C code to QM?
Posts: 12,092
Threads: 142
Joined: Dec 2002
__BE_CONFIG1 is union, not struct.
Posts: 795
Threads: 136
Joined: Feb 2009
so everytime i find an union in C code and want to convert in QM, I must use this
convention with empty brackets at the beginning of the second to last structure of the union?
Posts: 12,092
Threads: 142
Joined: Dec 2002
Yes.
C:
union X { int a; double b; byte c; };
QM:
type X int'a []double'b []byte'c
C#:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct X { [FieldOffset(0)] public int a; [FieldOffset(0)] public double b; [FieldOffset(0)] public byte c; };
Posts: 795
Threads: 136
Joined: Feb 2009
ok, understood, so simple in fact...
Going under the hood is sometimes hard.
thanks for your patience and knowledge Gintaras.
|