📄 wave file format.mht
字号:
both 'data' and 'slnt' chunks), then fccChunk will specify 'data' or =
'slnt'=20
depending upon in which type of chunk the referenced waveform data is =
found.</P>
<P>The dwChunkStart and dwBlockStart fields are set to 0 for an =
uncompressed=20
WAVE file that contains one 'data' chunk. These fields are used only for =
WAVE=20
files that contain a Wave List (with multiple 'data' and 'slnt' chunks), =
or for=20
a compressed file containing a 'data' chunk. (Actually, in the latter =
case,=20
dwChunkStart is also set to 0, and only dwBlockStart is used). Again, I =
want to=20
emphasize that you can avoid all of this unnecessary crap if you avoid =
hassling=20
with compressed files, or Wave Lists, and instead stick to the sensible=20
basics.</P>
<P>The dwChunkStart field specifies the byte offset of the start of the =
'data'=20
or 'slnt' chunk which actually contains the waveform data to which this =
CuePoint=20
refers. This offset is relative to the start of the first chunk within =
the Wave=20
List. (ie, It's the byte offset, within the Wave List, of where the =
'data' or=20
'slnt' chunk of interest appears. The first chunk within the List would =
be at an=20
offset of 0).</P>
<P>The dwBlockStart field specifies the byte offset of the start of the =
block=20
containing the position. This offset is relative to the start of the =
waveform=20
data within the 'data' or 'slnt' chunk.</P>
<P>The dwSampleOffset field specifies the sample offset of the cue point =
relative to the start of the block. In an uncompressed file, this =
equates to=20
simply being the offset within the waveformData array. Unfortunately, =
the WAVE=20
documentation is much too ambiguous, and doesn't define what it means by =
the=20
term "sample offset". This could mean a byte offset, or it could mean =
counting=20
the sample points (for example, in a 16-bit wave, every 2 bytes would be =
1=20
sample point), or it could even mean sample frames (as the loop offsets =
in AIFF=20
are specified). Who knows? The guy who conjured up the Cue chunk =
certainly isn't=20
saying. I'm assuming that it's a byte offset, like the above 2 =
fields.</P>
<H4>Cue Chunk</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>#define</FONT> CueID 'cue ' <FONT color=3Dbrown>/* chunk =
ID for Cue Chunk */</FONT>
<FONT color=3Dgreen>typedef struct</FONT> {
ID chunkID;
<FONT color=3Dgreen>long</FONT> chunkSize;
<FONT color=3Dgreen>long</FONT> dwCuePoints;
CuePoint points[];
} CueChunk;
</FONT></B></PRE>The ID is always <B>cue </B>. chunkSize is the number =
of bytes=20
in the chunk, not counting the 8 bytes used by ID and Size fields.=20
<P>The dwCuePoints field is the number of CuePoint structures in the Cue =
Chunk.=20
If dwCuePoints is not 0, it is followed by that many CuePoint =
structures, one=20
after the other. Because all fields in a CuePoint structure are an even =
number=20
of bytes, the length of any CuePoint will always be even. Thus, =
CuePoints are=20
packed together with no unused bytes between them. The CuePoints need =
not be=20
placed in any particular order.</P>
<P>The Cue chunk is optional. No more than one Cue chunk can appear in a =
WAVE.</P>
<HR>
<H3><FONT color=3D#ff8040>Playlist chunk</FONT></H3>The Playlist (plst) =
chunk=20
specifies a play order for a series of cue points. The Cue chunk =
contains all of=20
the cue points, but the Playlist chunk determines how those cue points =
are used=20
when playing back the waveform (ie, which cue points represent looped =
sections,=20
and in what order those loops are "played"). The Playlist chunk contains =
one or=20
more Segment structures, each of which identifies a looped section of =
the=20
waveform (in conjunction with the CuePoint structure with which it is=20
associated).=20
<H4>Segment Structure</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>typedef struct</FONT> {
<FONT color=3Dgreen>long</FONT> dwIdentifier;
<FONT color=3Dgreen>long</FONT> dwLength;
<FONT color=3Dgreen>long</FONT> dwRepeats;
} Segment;
</FONT></B></PRE>The dwIdentifier field contains a unique number (ie, =
different=20
than the ID number of any other Segment structure). This field should =
correspond=20
with the dwIndentifier field of some CuePoint stored in the Cue chunk. =
In other=20
words, this Segment structure contains the looping information =
associated with=20
that CuePoint structure with the same ID number.=20
<P>The dwLength field specifies the length of the section in samples =
(ie, the=20
length of the looped section). Note that the start position of the loop =
would be=20
the dwSampleOffset of the referenced CuePoint structure in the Cue =
chunk. (Or,=20
you may need to hassle with the dwChunkStart and dwBlockStart fields as =
well if=20
dealing with a Wave List or compressed data).</P>
<P>The dwRepeats field specifies the number of times to play the loop. I =
assume=20
that a value of 1 means to repeat this loop once only, but the WAVE=20
documentation is very incomplete and omits this important information. I =
have no=20
idea how you would specify an infinitely repeating loop. Certainly, the =
person=20
who conjured up the Playlist chunk appears to have no idea whatsoever. =
Due to=20
the ambiguities, inconsistencies, inefficiencies, and omissions of the =
Cue and=20
Playlist chunks, I very much recommend that you use the Sampler chunk =
(described=20
later) to replace them.</P>
<H4>Playlist chunk</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>#define</FONT> PlaylistID 'plst' <FONT color=3Dbrown>/* =
chunk ID for Playlist Chunk */</FONT>
<FONT color=3Dgreen>typedef struct</FONT> {
ID chunkID;
<FONT color=3Dgreen>long</FONT> chunkSize;
<FONT color=3Dgreen>long</FONT> dwSegments;
Segment Segments[];
} PlaylistChunk;
</FONT></B></PRE>The ID is always <B>plst</B>. chunkSize is the number =
of bytes=20
in the chunk, not counting the 8 bytes used by ID and Size fields.=20
<P>The dwSegments field is the number of Segment structures in the =
Playlist=20
Chunk. If dwSegments is not 0, it is followed by that many Segment =
structures,=20
one after the other. Because all fields in a Segment structure are an =
even=20
number of bytes, the length of any Segment will always be even. Thus, =
Segments=20
are packed together with no unused bytes between them. The Segments need =
not be=20
placed in any particular order.</P>
<HR>
<H3><FONT color=3D#ff8040>Associated Data List</FONT></H3>The Associated =
Data List=20
contains text "labels" or "names" that are associated with the CuePoint=20
structures in the Cue chunk. In other words, this list contains the text =
labels=20
for those CuePoints.=20
<P>Again, we're talking about another imbedded IFF List within the WAVE =
file.=20
NOOOOOOOOOOOOOO!!!! What's a List? A List is simply a "master chunk" =
that=20
contains several "sub-chunks". Just like with any other chunk, the =
"master=20
chunk" has an ID and chunkSize, but inside of this chunk are sub-chunks, =
each=20
with its own ID and chunkSize. Of course, the chunkSize for the master =
chunk=20
(ie, List) includes the size of all of these sub-chunks (including their =
ID and=20
chunkSize fields).</P>
<P>The "Type ID" for the Associated Data List is "adtl". Remember that =
an IFF=20
list header has 3 fields:</P><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>typedef struct</FONT> {
ID listID; <FONT color=3Dbrown>/* 'list' */</FONT>
<FONT color=3Dgreen>long</FONT> chunkSize; <FONT color=3Dbrown>/* =
includes the Type ID below */</FONT>
ID typeID; <FONT color=3Dbrown>/* 'adtl' */</FONT>
} ListHeader;
</FONT></B></PRE>There are several sub-chunks that may be found inside =
of the=20
Associated Data List. The ones that are important to WAVE format have =
IDs of=20
"labl", "note", or "ltxt". Ignore the rest. Here are those 3 sub-chunks =
and=20
their fields:=20
<P>The Associated Data List is optional. The WAVE documentation doesn't =
specify=20
if more than one can be contained in a WAVE file.</P>
<H4>Label Chunk</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>#define</FONT> LabelID 'labl' <FONT color=3Dbrown>/* =
chunk ID for Label Chunk */</FONT>
<FONT color=3Dgreen>typedef struct</FONT> {
ID chunkID;
<FONT color=3Dgreen>long</FONT> chunkSize;
<FONT color=3Dgreen>long</FONT> dwIdentifier;
<FONT color=3Dgreen>char</FONT> dwText[];
} LabelChunk;
</FONT></B></PRE>The ID is always <B>labl</B>. chunkSize is the number =
of bytes=20
in the chunk, not counting the 8 bytes used by ID and Size fields nor =
any=20
possible pad byte needed to make the chunk an even size (ie, chunkSize =
is the=20
number of remaining bytes in the chunk after the chunkSize field, not =
counting=20
any trailing pad byte).=20
<P>The dwIdentifier field contains a unique number (ie, different than =
the ID=20
number of any other Label chunk). This field should correspond with the=20
dwIndentifier field of some CuePoint stored in the Cue chunk. In other =
words,=20
this Label chunk contains the text label associated with that CuePoint =
structure=20
with the same ID number.</P>
<P>The dwText array contains the text label. It should be a =
null-terminated=20
string. (The null byte is included in the chunkSize, therefore the =
length of the=20
string, including the null byte, is chunkSize - 4).</P>
<H4>Note Chunk</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>#define</FONT> NoteID 'note' <FONT color=3Dbrown>/* chunk =
ID for Note Chunk */</FONT>
<FONT color=3Dgreen>typedef struct</FONT> {
ID chunkID;
<FONT color=3Dgreen>long</FONT> chunkSize;
<FONT color=3Dgreen>long</FONT> dwIdentifier;
<FONT color=3Dgreen>char</FONT> dwText[];
} NoteChunk;
</FONT></B></PRE>The Note chunk, whose ID is <B>note</B>, is otherwise =
exactly=20
the same as the Label chunk (ie, same fields). See what I mean about =
pointless=20
duplication? But, in theory, a Note chunk contains a "comment" about a =
CuePoint,=20
whereas the Label chunk is supposed to contain the actual CuePoint =
label. So,=20
it's possible that you'll find both a Note and Label for a specific =
CuePoint,=20
each containing different text.=20
<H4>Labeled Text Chunk</H4><PRE><B><FONT size=3D3><FONT =
color=3Dgreen>#define</FONT> LabelTextID 'ltxt' <FONT color=3Dbrown>/* =
chunk ID for Labeled Text Chunk */</FONT>
<FONT color=3Dgreen>typedef struct</FONT> {
ID chunkID;
<FONT color=3Dgreen>long</FONT> chunkSize;
<FONT color=3Dgreen>long</FONT> dwIdentifier;
<FONT color=3Dgreen>long</FONT> dwSampleLength;
<FONT color=3Dgreen>long</FONT> dwPurpose;
<FONT color=3Dgreen>short</FONT> wCountry;
<FONT color=3Dgreen>short</FONT> wLanguage;
<FONT color=3Dgreen>short</FONT> wDialect;
<FONT color=3Dgreen>short</FONT> wCodePage;
<FONT color=3Dgreen>char</FONT> dwText[];
} LabelTextChunk;
</FONT></B></PRE>The ID is always <B>ltxt</B>. chunkSize is the number =
of bytes=20
in the chunk, not counting the 8 bytes used by ID and Size fields nor =
any=20
possible pad byte needed to make the chunk an even size (ie, chunkSize =
is the=20
number of remaining bytes in the chunk after the chunkSize field, not =
counting=20
any trailing pad byte).=20
<P>The dwIdentifier field is the same as the Label chunk.</P>
<P>The dwSampleLength field specifies the number of sample points in the =
segment=20
of waveform data. In other words, a Labeled Text chunk contains a label =
for a=20
<B>section</B> of the waveform data, not just a specific point, for =
example the=20
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -