📄 wave.htm
字号:
audio channels may be represented. for multichannel sounds, single sample points from each
channel are interleaved. a set of interleaved sample points is called a sample frame.</p>
<p>the actual waveform data is stored in another chunk, the sound data chunk, which will
be described later.</p>
<p>the numsampleframes field contains the number of sample frames. this is not necessarily
the same as the number of bytes nor the number of sample points in the sound data chunk
(ie, it won't be unless you're dealing with a mono waveform). the total number of sample
points in the file is numsampleframes times numchannels.</p>
<p>the samplesize is the number of bits in each sample point. it can be any number from 1
to 32.</p>
<p>the samplerate field is the sample rate at which the sound is to be played back in
sample frames per second.</p>
<p>one, and only one, common chunk is required in every form aiff.</p>
<hr>
<h3>sound data chunk</h3>
<p>the sound data chunk contains the actual sample frames (ie, all channels of waveform
data).</p>
<pre>
#define sounddataid 'ssnd' /* chunk id for sound data chunk */
typedef struct {
id chunkid;
long chunksize;
unsigned long offset;
unsigned long blocksize;
unsigned char waveformdata[];
} sounddatachunk;
</pre>
<p>the id is always <b>ssnd</b>. chunksize is the number of bytes in the chunk, not
counting the 8 bytes used by id and size fields nor any possible pad byte needed to make
the chunk an even size (ie, chunksize is the number of remaining bytes in the chunk after
the chunksize field, not counting any trailing pad byte). </p>
<p>you can determine how many bytes of actual waveform data there is by subtracting 8 from
the chunksize. remember that the number of sample frames, bit resolution, and other
information is gotten from the common chunk.</p>
<p>the offset field determines where the first sample frame in the waveformdata starts.
the offset is in bytes. most applications won't use offset and should set it to zero. use
for a non-zero offset is explained in "block-aligning waveform data".</p>
<p>the blocksize is used in conjunction with offset for block-aligning waveform data. it
contains the size in bytes of the blocks that waveform data is aligned to. as with offset,
most applications won't use blocksize and should set it to zero. more information on
blocksize is in "block-aligning waveform data".</p>
<p>the waveformdata array contains the actual waveform data. the data is arranged into
what are called <em>sample frames</em> the number of sample frames in waveformdata is
determined by the numsampleframes field in the common chunk. for more information, see
"sample points and sample frames".</p>
<p>the sound data chunk is required unless the numsampleframes field in the common chunk
is zero. one, and only one, sound data chunk may appear in a form aiff.</p>
<h3>block-aligning waveform data</h3>
<p>there may be some applications that, to ensure real time recording and playback of
audio, wish to align waveform data into fixed-size blocks. this alignment can be
accomplished with the offset and blocksize parameters of the sound data chunk, as shown
below. </p>
<pre>
_________________ ___________________________________ _________________
|\\\\ unused \\\\\| sample frames |\\\\ unused \\\\\|
|_________________|___________________________________|_________________|
<-- offset><- numsampleframes sample frames>
| blocksize | | | |
|<- bytes>| | | |
|_________________|_________________|_________________|_________________|
block n-1 block n block n+1 block n+2
</pre>
<p>above, the first sample frame starts at the beginning of block n. this is accomplished
by skipping the first offset bytes (ie, some stored pad bytes) of the waveformdata. note
that there may also be pad bytes stored at the end of waveformdata to pad it out so that
it ends upon a block boundary. </p>
<p>the blocksize specifies the size in bytes of the block to which you would align the
waveform data. a blocksize of 0 indicates that the waveform data does not need to be
block-aligned. applications that don't care about block alignment should set the blocksize
and offset to 0 when creating aiff files. applications that write block-aligned waveform
data should set blocksize to the appropriate block size. applications that modify an
existing aiff file should try to preserve alignment of the waveform data, although this is
not required. if an application does not preserve alignment, it should set the blocksize
and offset to 0. if an application needs to realign waveform data to a different sized
block, it should update blocksize and offset accordingly.</p>
<hr>
<h3>the marker chunk</h3>
<p>the marker chunk contains markers that point to positions in the waveform data. markers
can be used for whatever purposes an application desires. the instrument chunk, defined
later in this document, uses markers to mark loop beginning and end points. </p>
<p>a marker structure is as follows:</p>
<pre>
typedef short markerid;
typedef struct {
markerid id;
unsigned long position;
pstring markername;
} marker;
</pre>
<p>the id is a number that uniquely identifies that marker within an aiff. the id can be
any positive non-zero integer, as long as no other marker within the same form aiff has
the same id. </p>
<p>the marker's position in the waveformdata is determined by the position field. markers
conceptually fall between two sample frames. a marker that falls before the first sample
frame in the waveform data is at position 0, while a marker that falls between the first
and second sample frame in the waveform data is at position 1. therefore, the units for
position are sample frames, not bytes nor sample points.</p>
<pre>
sample frames
___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
| | | | | | | | | | | | |
|___|___|___|___|___|___|___|___|___|___|___|___|
^ ^ ^
position 0 position 5 position 12
</pre>
<p>the markername field is a pascal-style text string containing the name of the mark. </p>
<p>note: some "ea iff 85" files store strings as c-strings (text bytes followed
by a null terminating character) instead of pascal-style strings. audio iff uses pstrings
because they are more efficiently skipped over when scanning through chunks. using
pstrings, a program can skip over a string by adding the string count to the address of
the first character. c strings require that each character in the string be examined for
the null terminator.</p>
<h3>marker chunk format</h3>
<p>the format for the data within a marker chunk is shown below. </p>
<pre>
#define markerid 'mark' /* chunkid for marker chunk */
typedef struct {
id chunkid;
long chunksize;
unsigned short nummarkers;
marker markers[];
} markerchunk;
</pre>
<p>the id is always <b>mark</b>. chunksize is the number of bytes in the chunk, not
counting the 8 bytes used by id and size fields. </p>
<p>the nummarkers field is the number of marker structures in the marker chunk. if
nummarkers is not 0, it is followed by that many marker structures, one after the other.
because all fields in a marker structure are an even number of bytes, the length of any
marker will always be even. thus, markers are packed together with no unused bytes between
them. the markers need not be placed in any particular order.</p>
<p>the marker chunk is optional. no more than one marker chunk can appear in a form aiff.</p>
<hr>
<h3>the instrument chunk</h3>
<p>the instrument chunk defines basic parameters that an instrument, such as a midi
sampler, could use to play the waveform data. </p>
<h3>looping</h3>
<p>waveform data can be looped, allowing a portion of the waveform to be repeated in order
to lengthen the sound. the structure below describes a loop. </p>
<pre>
typedef struct {
short playmode;
markerid beginloop;
markerid endloop;
} loop;
</pre>
<p>a loop is marked with two points, a begin position and an end position. there are two
ways to play a loop, forward looping and forward/backward looping. in the case of forward
looping, playback begins at the beginning of the waveform, continues past the begin
position and continues to the end position, at which point playback starts again at the
begin position. the segment between the begin and end positions, called the loop segment,
is played repeatedly until interrupted by some action, such as a musician releasing a key
on a musical controller. </p>
<pre>
___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
sample frames | | | |<--- loop segment>| | | |
|___|___|___|___|___|___|___|___|___|___|___|___|
^ ^
begin position end position
</pre>
<p>with forward/backward looping, the loop segment is first played from the begin position
to the end position, and then played backwards from the end position to the begin
position. this flip-flop pattern is repeated over and over again until interrupted. </p>
<p>the playmode specifies which type of looping is to be performed:</p>
<pre>#define nolooping 0
#define forwardlooping 1
#define forwardbackwardlooping 2
</pre>
<p>if nolooping is specified, then the loop points are ignored during playback. </p>
<p>the beginloop is a marker id that marks the begin position of the loop segment.</p>
<p>the endloop marks the end position of a loop. the begin position must be less than the
end position. if this is not the case, then the loop segment has 0 or negative length and
no looping takes place.</p>
<h3>the instrument chunk format</h3>
<p>the format of the data within an instrument chunk is described below. </p>
<pre>
#define instrumentid 'inst' /*chunkid for instruments chunk */
typedef struct {
id chunkid;
long chunksize;
char basenote;
char detune;
char lownote;
char highnote;
char lowvelocity;
char highvelocity;
short gain;
loop sustainloop;
loop releaseloop;
} instrumentchunk;
</pre>
<p>the id is always <b>inst</b>. chunksize should always be 20 since there are no fields
of variable length. </p>
<p>the basenote is the note number at which the instrument plays back the waveform data
without pitch modification (ie, at the same sample rate that was used when the waveform
was created). units are midi note numbers, and are in the range 0 through 127. middle c is
60.</p>
<p>the detune field determines how much the instrument should alter the pitch of the sound
when it is played back. units are in cents (1/100 of a semitone) and range from -50 to
+50. negative numbers mean that the pitch of the sound should be lowered, while positive
numbers mean that it should be raised.</p>
<p>the lownote and highnote fields specify the suggested note range on a keyboard for
playback of the waveform data. the waveform data should be played if the instrument is
requested to play a note between the low and high note numbers, inclusive. the base note
does not have to be within this range. units for lownote and highnote are midi note
values.</p>
<p>the lowvelocity and highvelocity fields specify the suggested range of velocities for
playback of the waveform data. the waveform data should be played if the note-on velocity
is between low and high velocity, inclusive. units are midi velocity values, 1 (lowest
velocity) through 127 (highest velocity).</p>
<p>the gain is the amount by which to change the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -