I am trying to define the TWaveFormatExtensible
type, but I am not sure if am I declaring correctly the Samples
union. Here is the original declaration from header file (Windows SDK 10.0.17763.0):
typedef struct {
WAVEFORMATEX Format;
union {
WORD wValidBitsPerSample; /* bits of precision */
WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */
WORD wReserved; /* If neither applies, set to zero. */
} Samples;
DWORD dwChannelMask; /* which channels are */
/* present in stream */
GUID SubFormat;
}
And this is what I've tried:
type
TWAVEFORMATEX = record
wFormatTag: Word;
nChannels: LongWord;
nSamplesPerSec: Word;
nAvgBytesPerSec: LongWord;
nBlockAlign: Word;
wBitsPerSample: Word;
cbSize: Word;
end;
TWaveFormatExtensible = record
Format: TWAVEFORMATEX;
dwChannelMask: LongWord;
SubFormat: Integer;
case Word of
0: (wValidBitsPerSample: Word;);
1: (wSamplesPerBlock: Word;);
2: (wReserved: Word;);
end;
But that's not correct. How would one declare a union inside a record structure in Delphi?
You can declare a structure or union type separately from the definition of variables of that type, as described in Structure and union type definition and Structure and union variable declarations; or you can define a structure or union data type and all variables that have that type in one statement, as described in ...
A structure can be nested inside a union and it is called union of structures. It is possible to create a union inside a structure.
union { int no; char name[20], float price; }; In this, the size of the member, name is more than the size of other members (sr, price) so the size of a union in memory (char × 20 = 20 byte) will be 20 bytes.
Union is used when you have to use the same memory location for two or more data members. It enables you to hold data of only one data member.
The fields of the structure must be in the same order as in the original (C++) declaration. But there's a problem: the original declaration puts the Samples
variant in the middle of the record and that is not allowed in Delphi.
You can solve this by declaring the variant part as a separate record and then include that record as a field in the final structure.
TWaveFormatExtensibleSamples = record
case Word of
0: (wValidBitsPerSample: Word;);
1: (wSamplesPerBlock: Word;);
2: (wReserved: Word;);
end;
and then construct the final structure:
TWaveFormatExtensible = record
Format: TWAVEFORMATEX;
Samples: TWaveFormatExtensibleSamples;
dwChannelMask: DWORD;
SubFormat: TGUID;
end;
edit: The documentation for records with variant parts, state:
A record type can have a variant part, which looks like a case statement. The variant part must follow the other fields in the record declaration.
This concerns variant parts without an enclosing record declaration.
However, as Remy Lebeau pointed out, a record with the variant part can be directly declared in the TWaveFormatExtensible
declaration as part of the structure, in between other fields:
TWaveFormatExtensible = record
Format: TWAVEFORMATEX;
Samples: record
case Word of
0: (wValidBitsPerSample: Word;);
1: (wSamplesPerBlock: Word;);
2: (wReserved: Word;);
end;
dwChannelMask: DWORD;
SubFormat: TGUID;
end;
So this can be used as well as the separately declared TWaveFormatExtensibleSamples
record.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With