
File Type: $D8 (216)
Auxiliary Type: $0001
Full Name: Audio Interchange File Format AIFF-C File
Short Name: AIFF-C File
Written by: Matt Deatherage March 1991
Files of this type and auxiliary type contain sampled sounds in Apple Computer's
Audio Interchange File Format AIFF-C (AIFF-C).
The Audio Interchange File Format (Audio IFF) provides a standard for storing
sampled sounds. The format is quite flexible, allowing the storage of monaural
or multichannel sampled sounds at a variety of sample rates and sample widths.
This Note describes version 1.0 (February 3, 1991) of AIFF-C. This Note
describes AIFF-C as it pertains to Apple II developers.
AIFF-C conforms to the "EA IFF 85" Standard for Interchange
Format Files developed by Electronic Arts.
Although AIFF-C is an interchange format, application designers should
find it flexible enough to use as a data storage format as well. If an application
does choose to use a different storage format, it should be able to convert
to and from the format defined in this document. This ability to convert
will facilitate the sharing of sound data between applications. Apple
Computer officially recommends that all sound applications read and write
AIFF-C files.
AIFF-C is the result of several meetings held with music developers over
a period of ten months during 1987 and 1988 as well as revisions to the
original Audio IFF standard conducted during the summer of 1990. Apple Computer
greatly appreciates the comments and cooperation provided by all developers
who helped define this standard.
Another "EA IFF 85" sound storage format is "8SVX"
IFF 8-bit Sampled Voice, by Electronic Arts. "8SVX," which
handles eight-bit monaural samples, is intended mainly for storing sound
for playback on personal computers. AIFF-C is intended for use with a larger
variety of computers, sampled sound instruments, sound software applications,
and high fidelity recording devices.
The official name for this standard is Audio Interchange File Format AIFF-C.
If an application program needs to present the name of this format to a
user, such as in a "Save As..." dialog box, the name can be abbreviated
to Audio IFF or AIFF-C.
Differences between Audio IFF and AIFF-C
The differences between the original AIFF and AIFF-C were kept to a minimum.
Applications which currently support AIFF should be easily upgradable to
AIFF-C. If you are unfamiliar with Audio IFF, you might want to skip directly
to "The Chunk Concept" later in this Note.
The following changes have been made from AIFF:
* The FORM identifier was changed from "AIFF"
to "AIFC". This distinguishes AIFF-C files from AIFF
files. Existing AIFF programs, until they are upgraded, will simply ignore
AIFF-C files. See the explanation below for this change.
* The Common Chunk has been extended to include a compression type ID and
a compression type name. AIFF-C is thus capable of storing compressed audio
data generated from any compression algorithm.
* The Sound Data Chunk can contain compressed audio data. The Chunk format
has not been modified.
* The Sound Accelerator (Saxel) Chunk is new. It is designed to eliminate
initial "artifacts" caused by the decompression algorithm when
playback begins at a random point defined by a Marker.
* The Format Version Chunk is new. This Chunk is designed to provide a smooth
transition for potential future upgrades to the AIFF-C specification.
Transition from FORM AIFF to FORM AIFC
Renaming the FORM type from AIFF to AIFC was
done to minimize confusion for the end user. Imagine a possible scenario
if the FORM type was not changed: A user running an application which
stored compressed audio in AIFF-C format would save his compressed audio
data as an AIFF File type (via the "Save As ..." dialog box).
He could then launch another application which reads AIFF, but not AIFF-C,
and the application would not be able to play his sound. The application
may even crash. By making the difference between the file types explicit,
the user will not experience this problem. The user still won't be able
to transfer compressed audio data to the second application, but at least
he will know why.
Here are the guidelines which developers should follow to aid the transition
from AIFF to AIFF-C:
1. Applications which currently read FORM AIFF
files should also be able to read FORM AIFC files.
2. Applications which currently create FORM AIFF
files should maintain this capability for now, but should offer the FORM
AIFC format as the default option to the user.
3. New applications which have not supported AIFF should strongly consider
supporting only AIFF-C, at least for the creation of audio files.
The Chunk Concept
The "EA IFF 85" Standard for Interchange Format Files defines
an overall structure for storing data in files. AIFF-C conforms to the "EA
IFF 85" standard. This Note describes those portions of "EA IFF
85" that are germane to AIFF-C. For a more complete discussion of "EA
IFF 85," please refer to "EA IFF 85" Standard for Interchange
Format Files.
AIFF-C, like all IFF-style storage formats, is a series of discrete pieces,
or "chunks." Each chunk has an eight-byte "header,"
which is as follows:
ckID 4 Bytes The ID for this chunk. These four bytes must be ASCII
characters in the range $20-$7F. Spaces may not precede printing characters,
although trailing spaces are allowed. Characters outside the range $20-$7F
are forbidden. A program can determine how to interpret the chunk data by
examining ckID.
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
You may think of this value as the offset to the end of the chunk. Note
that this is a Reverse Long; the bytes are stored high byte first.
ckData Chunk The data, specific to each individual chunk. There are
exactly ckSize bytes of data here. If the length of the chunk is odd, a
pad byte of $00 must be added at the end. The pad byte is not included in
ckSize.
Since AIFF-C is an interchange format, it will come as no surprise to find
that all constants, such as each chunk's ckSize field, are stored in reverse
format (the bytes of multiple-byte values are stored with the high-order
bytes first). This is true for all constants, which are marked in their
individual descriptions by the Reverse notation.
Note: All numeric values in this Note are signed unless otherwise
noted. This is different from the normal File Type Note convention.
An AIFF-C file is a collection of a number of different types of chunks.
There is a Common Chunk which contains important parameters describing the
sampled sound, such as its length and sample rate. There is a Sound Data
Chunk which contains the actual audio samples. There are several other optional
chunks which define markers, list instrument parameters, store application-specific
information, etc. All of these chunks are described in detail in this Note.
File Structure
The chunks in an AIFF-C file are grouped together in a container chunk.
"EA IFF 85" Standard for Interchange Format Files defines
a number of container chunks, but the one used by AIFF-C is called a FORM.
A FORM has the following format:
ckID 4 Bytes The ID for this chunk. These four bytes must be "FORM."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
You may think of this value as the offset to the end of the chunk. Note
that this is a Reverse Long; the bytes are stored high byte first. Also
note that the data portion of the chunk is broken into two parts, formType
and chunks.
formType 4 Bytes Describes what's in the FORM chunk. For
AIFF-C files, formType is always "AIFC." This indicates
that the chunks within the FORM pertain to sampled sound. A FORM
chunk of formType AIFC is called a FORM AIFC.
chunks Bytes The chunks contained within the FORM. These
chunks are called local chunks. A FORM AIFC along with
its local chunks make up an AIFF-C file.
Figure 1 is a pictorial representation of a simple AIFF-C file. It consists
of a single FORM AIFC which contains two local chunks, a Common
Chunk, and a Sound Data Chunk.

Figure 1-Simple AIFF-C File
There are no restrictions on the ordering of local chunks within a FORM
AIFC.
The FORM AIFC is stored in a file with file type $D8 and auxiliary
type $0001. AIFF-C files may be identified in other file systems as well.
On a Macintosh under MFS or HFS, the FORM AIFC is stored in the
data fork of a file with file type "AIFC." This is the same as
the formType of the FORM AIFC.
Note: Applications should not store any data in the resource fork
of an AIFF-C file, since this information may not be preserved by all applications
or in translation to foreign file systems. Applications can use the Application
Specific Chunk, described later in this Note, to store extra information
specific to their application.
In file systems that use file extensions, such as MS-DOS or UNIX, it is
recommended that AIFF-C file names have the extension ".AFC."
A more detailed visual example of an AIFF-C file may be found later in this
Note. Please refer to it as often as necessary while reading the remainder
of this Note.
Local Chunk Types
The formats of the different local chunk types found within a FORM AIFC
are described in the following sections, as are their ckIDs.
There are two types of chunks: required and optional. The Common Chunk is
required. The Sound Data chunk is required if the sampled sound has a length
greater than zero. All other chunks are optional. All applications that
use FORM AIFC must be able to read the required chunks and can
choose to selectively ignore the optional chunks. A program that copies
a FORM AIFC should copy all the chunks in the FORM AIFC,
even if it chooses not to interpret the optional chunks.
Dealing with Unrecognized Local Chunks
When reading an IFF file, your program may encounter local chunk types that
it doesn't recognize, perhaps extensions defined after your program was
written. In a FORM AIFC, this situation also applies to
Application-Specific Chunks with unrecognized application signatures. (The
application signature acts as a chunk subtype.) Clearly your program cannot
process the contents of unrecognized chunks.
So what should your program do when it encounters unrecognized chunks in
an IFF FORM? The safest thing is to simply discard them while reading
the FORM. If your program copies the FORM without edits,
then it's nicer (but not necessary) to copy unrecognized chunks also. But
if your program modifies the data in any way, then it must discard
all unrecognized chunks since it can't possibly update the unrecognized
data to be consistent with the modifications.
To ensure that this standard remains usable by all developers across machine
families, only Apple Computer, Inc. should define new chunk types for FORM
AIFC. If you have suggestions for new chunk types, Apple is happy to
listen. Please send all comments to the address listed in "About File
Type Notes" to the attention of "AIFF-C Suggestions."
The Format Version Chunk
The Common Chunk describes fundamental parameters of the sampled sound.
ckID 4 Bytes The ID for this chunk. These four bytes must be "FVER."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
For the Format Version Chunk, this is always 4.
timeStamp Rev. Unsigned Long Indicates the version of AIFF-C with
which this file was created. Units are the number of seconds since 12:00
a.m. (midnight), January 1, 1904. This document describes Version 1 of AIFF-C,
for which the value of timeStamp should be $A2805140 (May 23, 1990, 2:40
PM).
Only Apple may alter the value of timeStamp.
Do not confuse the Format Version with the creation date of the file. The
Format Version refers to the rules embodied in this, or future, documents
which specify how an AIFF-C file is arranged. When your application checks
for compatibility with the Format Version chunk, do not do a range check
(e.g. less than or equal to this date). You must do an exact comparison
of dates to know for certain that your application can correctly read and
process a specific AIFF-C file. Do not modify the timeStamp value.
If you have a request for a new Format Version, please submit it to Apple
Computer at the address in "About File Type Notes". Through this
mechanism where only Apple Computer can issue official AIFF-C releases with
new timeStamps, we can ensure the maximum compatibility of AIFF-C files
across applications.
The Format Version Chunk is required. One and only one Format Version
Chunk must appear in a FORM AIFC.
Why the Format Version Chunk was added
"Gee, if we'd had a Version Chunk in AIFF, we wouldn't have to change
the FORM type for AIFF-C."--an anonymous AIFF File Type
Note author (circa 1990)
From the above proverb, we gained the wisdom to include a Format Version
Chunk in the AIFF-C specification. The philosophy is that the Chunk names
which you recognize will contain information in the format you are familiar
with. If you don't find a Chunk which your application requires, then examine
the Format Version Chunk to determine if the file is corrupted or if there
is a mismatch between your application and the file. In any case, you'll
be able to give a more enlightened message to the user.
See how the following steps simplify your life (and ours) to determine if
a FORM AIFC is usable:
When reading an AIFF-C file:
1. First, find the FORM AIFC field. If you don't find
it, issue an alert like "This file doesn't contain an AIFF-C standard
audio recording.", then exit from these directions.
2. Try to find all the chunks which are critical to your application (probably
COMM and SSND, but we can imagine an application that
only needs the COMM chunk, e.g. to determine the playback duration).
If found, those familiar chunk IDs indicate that the chunk contents are
in the format you expect. You're golden. Exit these directions.
3. If not found, don't crash yet. Instead, check for the Format Version
Chunk.
If you can find it and it does not contain a date which you recognize, issue
an alert like "This file contains an unrecognized version of the AIFF-C
standard." You may also want to indicate the file's Format Version
and the format versions which your application recognizes.
Otherwise, issue an alert with text similar to "This file seems to
be chopped cabbage." It might also be nice to say which Chunks are
missing.
Remember:
* In order to survive interchange and format evolution, reader programs
must be robust about chunk order, missing chunks, and unexpected chunks.
* Contrary to the original Audio IFF specification, when a program encounters
an unrecognized chunk, it should just skip it. Do not copy it to
a new, edited file. This is the general rule in IFF because there's
no way to maintain the integrity of unrecognized chunks when the surrounding
data is edited.
How the Format Version Chunk will help potential future upgrades
If and when we design evolutionary changes to the file format, we will try
to make the new representation backward compatible (e.g. just add new chunk
types). If we must change the format of existing data, then we will change
the relevant Chunk IDs. For example, let's say that the INST Chunk
needs to be upgraded to have more than 2 loop points. In this case, we would
replace the INST Chunk with a new Chunk--let's call it "LOOP".
In the transition time between widespread adoption of the new LOOP
Chunk, a FORM could contain both the old INST Chunk and
the new LOOP Chunk. Applications which know about the new LOOP
Chunk would be able to process it correctly, while preserving the INST
Chunk for other applications. Applications which do not use the INST
or LOOP Chunks are unaffected. Applications which need the old
INST Chunk can still use it, but should upgrade to the new LOOP
Chunk since there is no longer any guarantee that other (editing) applications
will preserve the old INST Chunk.
Here's how we would have upgraded AIFF to handle compressed audio, if we
had had a Format Version Chunk already in AIFF:
* Compression is optional. What follows is only for the compressed
case.
* Don't change the format of the COMM Chunk. Existing programs
can still read it.
* Add a "Compression Descriptor" Chunk containing the 4-letter
compression type code and the compression name string. (The code is for
programs. The string is for alerts when the code is unrecognized.)
* Replace the SSND Chunk with a Compressed Sound-Data Chunk "CSND".
(Existing programs will ignore it.)
* Change the Format Version date (for the sake of alerts).
* Add the optional Saxel Chunk.
We chose to change the FORM type from AIFF to AIFC
because, lacking the Format Version Chunk, existing applications would not
be able to issue a helpful error message. Some existing applications may
even crash if they did not find the SSND Chunk.
The Common Chunk
The Common Chunk describes fundamental parameters of the sampled sound.
ckID 4 Bytes The ID for this chunk. These four bytes must be "COMM."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
For the Common Chunk, this is 22 plus the length of the string (the string
includes a pad byte when needed to make it an even number of bytes in length).
numChannels Rev. Word The number of audio channels for the sound.
A value of 1 means monophonic sound, 2 means stereo, 4 means four-channel
sound, and so on. Any number of audio channels may be represented. The actual
sounds samples are stored in the Sound Data Chunk.
numSampleFrames Rev. Unsigned Long The number of sample frames in
the Sound Data Chunk. Sample frames are described below. Note that numSampleFrames
is the number of sample frames, not the number of bytes nor the number of
sample points (also described below) in the Sound Data Chunk. The total
number of sample points in the file is numSampleFrames multiplied by numChannels.
sampleSize Rev. Word The number of bits in each sample point. This
can be any number from 1 to 32.
sampleRate Rev. Extended The sample Rate at which the sound is to
be played back, in sample frames per second.
compressionType 4 Bytes The ID for the compression algorithm used.
A table of possible values is in the "More About Compression"
section of this Note.
compressionName String A Pascal string containing a human-readable
description of the compression algorithm used. A table of possible values
is in the "More About Compression" section of this Note.
One, and only one, Common Chunk is required in every FORM AIFC.
Sample Points and Sample Frames
A large part of interpreting AIFF-C files revolves around the two concepts
of sample points and sample frames.
An uncompressed sample point is a linear, two's-complement value representing
a sample of a sound at a given point in time. A sample point may be from
1 to 32 bits wide, as determined by sampleSize in the Common Chunk. Sample
points are stored in an integral number of contiguous bytes. One- to eight-bit
wide sample points are stored in one byte, 9- to 16-bit wide sample points
are stored in two bytes, 17- to 24-bit wide sample points are stored in
three bytes, and 25- to 32-bit wide sample points are stored in four bytes
(most significant byte first). When the width of a sample point is not a
multiple of eight bits, the sample point data is left justified, with the
remaining bits zeroed. An example case is illustrated in Figure 2. A 12-bit
sample point, binary 101000010111, is stored left justified in two bytes.
The remaining bits are set to zero.

Figure 2-A 12-Bit Sample Point
Sample frames are sets of sample points which are interleaved for multichannel
sound. Single sample points from each channel are interleaved such that
each sample frame is a sample point from the same moment in time for each
channel available. This is illustrated in Figure 3 for the stereo (two channel)
case.

Figure 3-Sample Frames for Multichannel Sound
For monophonic sound, a sample frame is a single sample point. For multichannel
sounds, you should follow the conventions in Figure 4.

Figure 4-Sample Frame Conventions for Multichannel Sound
Note: Portions of Figure 4 do not follow the Apple IIGS standard of
right on even channels and left on odd channels. The portions that do follow
this convention usually use channel two for right instead of channel zero
as most Apple IIGS standards. Be prepared to interpret data accordingly.
Sample frames are stored contiguously in order of increasing time. The sample
points within a sample frame are packed together; there are no unused bytes
between them. Likewise, the sample frames are packed together with no pad
bytes.
For compressed sounds, these definitions essentially hold but are modified
slightly. See the "More About Compression" section later in this
Note for all the details.
The Sound Data Chunk
The Sound Data Chunk contains the actual sample frames.
ckID 4 Bytes The ID for this chunk. These four bytes must be "SSND."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
If the sound data is padded to make it an even number of bytes in length,
the pad byte is not included in ckSize.
offset Rev. Unsigned Long Determines where the first sample frame
in the soundData starts, in bytes. Most applications will not use offset
and should set it zero. Use for a non-zero offset is explained below.
blockSize Rev. Unsigned Long Used in conjunction with offset for
block-aligning sound data. It contains the size in bytes of the blocks to
which soundData is aligned. As with offset, most applications will not use
blockSize and should set it to zero. More information on blockSize is given
below.
soundData Bytes Contains the actual sample frames that make up the
sound. The number of sample frames in the soundData is determined by the
numSampleFrames parameter in the Common Chunk.
The Sound Data Chunk is required unless the numSampleFrames field in the
Common Chunk is zero. A maximum of one Sound Data Chunk may appear in a
FORM AIFC.
Block-Aligning Sound Data
There may be some applications that, to ensure real time recording and playback
of audio, wish to align sampled sound data with fixed-size blocks. This
alignment can be accomplished with the offset and blockSize parameters of
the Sound Data Chunk, as shown in Figure 5.

Figure 5-Block-Aligned Sound Data
In Figure 5, the first sample frame starts at the beginning of block N.
This is accomplished by skipping the first offset bytes of the soundData.
Note too, that the soundData bytes can extend beyond valid sample frames,
allowing the soundData bytes to end on a block boundary as well.
The blockSize specifies the size in bytes of the block to which you would
align the sound data. A blockSize of zero indicates that the sound data
does not need to be block-aligned. Applications that don't care about block
alignment should set the blockSize and offset to zero when creating AIFF-C
files. Applications that write block-aligned sound data should set blockSize
to the appropriate block size. Applications that modify an existing AIFF-C
file should try to preserve alignment of the sound data, although this is
not required. If an application does not preserve alignment, it should set
the blockSize and offset to zero. If an application needs to realign sound
data to a different sized block, it should update blockSize and offset accordingly.
The Marker Chunk
The Marker Chunk contains markers that point to positions in the sound data.
Markers can be used for whatever purposes an application desires. The Instrument
Chunk, defined later in this Note, uses markers to mark loop beginning and
end points.
ckID 4 Bytes The ID for this chunk. These four bytes must be "MARK."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
numMarkers Rev. Unsigned Word The number of markers (defined below)
in the Marker Chunk. If non-zero, this is followed by the markers themselves.
Because all fields in a marker 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, although the markers themselves need not be ordered
in any particular manner.
Marker Markers Defined below.
A marker has the following format:
MarkerID Rev. Word The ID for this marker. This is a number that
uniquely identifies the marker within a FORM AIFC. The number can
be any positive, non-zero integer, as long as no other marker within the
same FORM AIFC has the same ID.
position Rev. Unsigned Long Determines the marker's position in the
sound data. Markers conceptually fall between two sample frames. A marker
that falls before the first sample frame in the sound data is at position
zero, while a marker that falls between the first and second sample frame
in the sound data is at position one. Units for position are sample frames,
not bytes nor sample points.
markerName String Pascal-type string containing the name of the mark.
If the length of the string is not an even number of bytes, include a zero
pad byte.

Figure 6-Uncompressed Sample Frame Marker Positions
Note: Some "EA IFF 85" files store strings as C-style strings
(null terminated). AIFF-C uses Pascal-style (length byte) strings because
they are easier to skip over when scanning a file or a chunk.
Apple recommends that audio editor programs update markers when the audio
data is edited.
The Marker Chunk is optional. No more than one Marker Chunk can appear in
a FORM AIFC.
Important: If a segment of sound data containing one or more Markers
is relocated in the sound stream, the Markers within the segment being moved
must be recalculated. If a segment of sound data is being deleted, all Markers
within that segment should be deleted and all Markers after that segment
must be adjusted. If sound data is inserted at a point in the sound data
stream, all Markers after that point must be adjusted. Any Saxels (see "Sound
Accelerator Chunks" later in is Note) which are associated with the
updated or deleted Markers must also be updated if affected by the new Marker
values. Updating Markers in some cases may have implications in the user
interface and the application designer should consider when the user should
be notified or asked about the consequences of an edit.
The Instrument Chunk
The Instrument Chunk defines basic parameters that an instrument, such as
a sample, could use to play the sound data.
ckID 4 Bytes The ID for this chunk. These four bytes must be "INST."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
For the Instrument Chunk, this field is always 20.
baseNote Byte The note at which the instrument plays the sound data
without pitch modification. Units are MIDI (Musical Instrument Digital Interface)
note numbers, and are in the range 0 through 127. Middle C is 60.
detune Byte Determines how much the instrument should alter the pitch
of the sound when it is played . Units are 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.
lowNote Byte Suggested lowest note on a keyboard for playback of
the sound data. The sound data should be played if the instrument is requested
to play a note between the lowNote and highNote, inclusive. The base note
does not have to be within this range. Units for lowNote and highNote are
MIDI note values.
highNote Byte Suggested highest note on a keyboard for playback of
the sound data. See the description of lowNote above.
lowVelocity Byte The low end of the suggested range of velocities
for playback of the sound data. The sound data should be played if the note-on
velocity is between lowVelocity and highVelocity, inclusive. Units are MIDI
velocity values, 1 (lowest velocity) through 127 (highest velocity).
highVelocity Byte The high end of the suggested range of velocities
for playback of the sound data. See the description of lowVelocity above.
gain Rev. Word The amount by which to change the gain of the sound
when it is played. Units are decibels. For example, 0 dB means no change,
6 dB means double the value of each sample point, while -6 dB means halve
the value of each sample point.
sustainLoop Loop A loop that is to be played when an instrument is
sustaining a sound. The format of loops is described below.
releaseLoop Loop A loop that is to be played when an instrument is
in the release phase of playing back a sound. The release phase usually
occurs after a key on an instrument is released. The format of loops is
described below.
Loops
Sound data can be looped, allowing a portion of the sound to be repeated
to lengthen the sound. 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 sound, 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 a user action, such as the release
of a key on a sampling instrument.

Figure 7-Sample Frame Looping
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.
To end a loop, finish the current loop section and don't repeat it any more.
This usually means playing to the end position, but it can mean playing
back to the beginning position if in the backwards half of a forward/backward
loop.
The following structure describes a loop:
playMode Rev. Word The type of looping to be performed.
0 = no looping
1 = Forward looping
2 = Forward/Backward looping
If 0 is specified, the loop points are ignored during playback.
beginLoop Rev. Word A Marker ID of the marker to the begin position.
endLoop Rev. Word A Marker ID of the marker to the end position.
The begin position must be less than the end position. If this is not the
case, the loop segment has zero or negative length and no looping occurs.
When looping on compressed sound data, make sure to pay particular
attention to setting the markers to the expanded sound data (see
the section on the Marker Chunk in this Note). Extra attention may be required
for smooth playback between the end of the looped data and the beginning
of the looped data due to discontinuities in the sound data encountered
by the expansion algorithm. In this case, the best recourse may be to modify
sound samples in the beginning or end part of the loop, or to avoid compressing
the looped data.
The Instrument Chunk is optional. No more than one Instrument Chunk can
appear in a FORM AIFC.
ASIF Note: The Apple IIGS Sampled Instrument Format also defines
a chunk with ID of "INST," which is not the same as the
AIFF-C Instrument Chunk. A good way to tell the two chunks apart in generic
IFF-style readers is by the ckSize fields. The AIFF-C Instrument Chunk's
ckSize field is always 20, whereas the Apple IIGS Sampled Instrument Format
Instrument Chunk's ckSize field, for structural reasons, can never be 20.
More About Compression
AIFF-C supports multiple types of compression. Although AIFF-C itself has
no intrinsic knowledge of any compression scheme (that is, there is nothing
in any of the chunks that depends on the behavior of any compression scheme),
it does include flexible support for multiple compression types--for identifying
the compression type, for informing users about it, and for using structures
like markers and loops with compressed sound data.
The Common Chunk contains a four-byte compressionType and an ASCII compressionName,
identifying the compression used to both the program and to the user. AIFF-C
debuts with five pre-defined compression values:
ASCII
compressionType compressionName meaning
NONE not compressed uncompressed, that is, straight digitized samples
ACE2 ACE 2-to-1 2-to-1 IIGS ACE (Audio Compression / Expansion)
ACE8 ACE 8-to-3 8-to-3 IIGS ACE (Audio Compression / Expansion)
MAC3 MACE 3-to-1 3-to-1 Macintosh Audio Compression / Expansion
MAC6 MACE 6-to-1 6-to-1 Macintosh Audio Compression / Expansion
Table 1--Existing Compression Schemes
Apple IIGS programs will normally not have access to MACE decompression,
and the reverse is true for Macintosh program with ACE decompression. In
these cases, you can use the ASCII compressionName to inform the user of
the sound's compressed source, giving him significantly more information
than "I can't decompress this sound."
The compression of sound is fairly straightforward. The diagrams below should
help illustrate the point for the four standard Apple compression algorithms.
Examples are for 8-bit linear monophonic sound samples.
Original uncompressed single channel sound data:

Figure 8--ACE 2:1 Apple IIGS Tool Frame size = 1 byte
Original uncompressed single channel sound data:

Figure 9--ACE 8:3 Apple IIGS Tool Frame size = 3 bytes
Original uncompressed single channel sound data:

Figure 10--3:1 Macintosh Audio Compression & Expansion
Frame size = 2 bytes
Original uncompressed single channel sound data:

Figure 11--6:1 Macintosh Audio Compression & Expansion
Frame size = 1 byte
The sample frame size is the basic unit of a compressed data block. For
the Macintosh 6:1 and the ACE 2:1 utilities, the frame size is 1 byte. For
the Macintosh 3:1 utility, the frame size is 2 bytes. For the ACE 8:3 utility,
the frame size is 3 bytes.
For storage of multichannel compressed sounds, the conventions listed
in the Common Chunk section should be followed, using a sample frame of
compressed sound data in place of uncompressed samples. Here are some examples:

Figure 12--Multichannel Compressed Sounds
Markers
Markers positions (see Marker Chunk section) are targeted to expanded (uncompressed)
sound data. Thus, a calculation must be done to map from a position in the
compressed data stream to the target position in the uncompressed sound
data. Fortunately, the existing compression utilities are linear - there
is a straight multiplicative ratio between the size of compressed sound
data to uncompressed sound data. Here is a table which can help you to calculate
the actual Marker position, given an offset index into the compressed (single
channel) sound data:
Compression (Bytes) Single channel sound data
Macintosh 3:1 Compressed data offset: 0 2 4 6 8 10 12 14
Marker Position: 0 6 12 18 24 30 36 42
Macintosh 6:1 Compressed data offset: 0 1 2 3 4 5 6 7
Marker Position: 0 6 12 18 24 30 36 42
ACE 2:1 Compressed data offset: 0 1 2 3 4 5 6 7
Marker Position: 0 2 4 6 8 10 12 14
ACE 8:3 Compressed data offset: 0 3 6 9 12 15 18 21
Marker Position: 0 8 16 24 32 40 48 56
Table 2--Marker Positions in Compressed Sound
It is possible to specify a Marker position which is not a multiple of the
compression rate (e.g. Marker position of 19 for Macintosh 3:1 compressed
sound data). In this case, the playback system must be contain enough intelligence
to:
1. Expand a compressed sample frame and discard the initial expanded sample(s)
before playback, and
2. Stop playback of samples before the last expanded sample. In the case
of a compressed sound which must be looped, this capability provides added
accuracy in determining the best loop points.
The Sound Accelerator Chunk
Audio decompression algorithms contain internal parameters which track the
behavior the sound being expanded. As these internal parameters depend on
the history of the previous sound samples, a simple attempt to begin playback
at arbitrary positions in the compressed sound data would result in artifacts
and distortion of the initial portion of the expanded sound. A Saxel stores
information about the compressed sound at a Marker position, thus providing
a means for high quality playback of random selections of compressed sound
data.
Background
Generally, a decompressor must start from the beginning of the compressed
data stream. It requires running state (e.g. internal filter parameters
or recently decompressed samples) to decompress the next sample. To start
playback at a marker point somewhere within the audio stream, you could:
a. decompress the data from the beginning and start playing once you reach
the marker, or
b. use additional data to locate the marked point within the compressed
data stream and load up the decompressor state, then start playing, or
c. compute the marked point within the compressed data stream (only possible
for fixed-ratio compression types), initialize the decompressor as if it
were starting at the beginning, and ignore the startup transient (only useful
for decompressors that would "settle down" in this case).
Method a is always possible as a fall-back. Method b is much faster, if
you have the required data. And that's what Saxel (Sound Accelerator) chunks
are for. Method c may be acceptable for certain applications and/or certain
classes of audio compression.
A Sound Accelerator (Saxel) chunk is used in combination with a Marker when
the sound data is compressed. The saxel carries the required data to locate
a point in the compressed data stream and to initialize the decompressor.
Saxels enable method b and a modified method a:
d. decompress the data from the previous marker that has a Saxel and start
playing once you reach the desired marker.
Note: As of this writing, the Saxel formats for Macintosh Audio Compression
and Expansion (MACE) compression had not been finalized, and are therefore
not included in this Note. Apple would welcome any ideas you have on the
topic at the address in "About File Type Notes."
The Sound Accelerator (Saxel) Chunk has the following format:
ckID 4 Bytes The ID for this chunk. These four bytes must be "SAXL."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
numSaxels Rev. Word The number of saxels in this chunk. Multiple
Saxel Chunks are allowed in a single FORM AIFC. Since
the total amount of Saxel data for a heavily-edited sound file may be quite
large, it may be easier for applications to store the various Saxels independently
of each other.
Saxels Saxels The Saxels themselves.
A Saxel has the following format:
MarkerID Rev. Word The ID of the marker for which the sound accelerator
data is to be used. It's considered good practice to supply a Saxel for
every marker--that way, you don't have to guess which markers will be used
as playback points.
size Rev. Word The length in bytes of the sound accelerator data,
saxelData. The data must be padded with a zero byte at the end if necessary
to make it an even number of bytes in length. This pad byte, if present,
is not included in size.
saxelData Bytes The Sound Acceleration Data
Sound Acceleration Data for Apple IIGS ACE Compression
Beginning with System Software 5.0.3, ACE has a way to retrieve the exact
state of the decompression algorithm, expressly for the inclusion of such
data in Saxel Chunks of AIFF-C. Future versions of ACE will include a tool
call to retrieve this data. For version 1.2 of ACE, the values to include
as saxelData are the first 16 bytes of ACE's direct page. ACE's direct page
can be obtained from the Tool Locator routine GetWAP with systemOrUser
= $0000 and tsNum = 29.
For versions later than 1.2 of ACE, the information can be obtained through
the new ACE calls GetACEExpState ($0D1D) and SetACEExpState
($0E1D). Both calls take the same parameter list and return no errors:

Figure 13--Stack Diagram for new ACE calls
Versions of ACE prior to 1.2 do not support retrieving the compression state
and should not be used with AIFF-C.
The MIDI Data Chunk
The MIDI Data Chunk can be used to store MIDI data. Please refer to Musical
Instrument Digital Interface Specification 1.0, available from the International
MIDI Association, for more details on MIDI.
The primary purpose of this chunk is to store MIDI System Exclusive messages,
although other types of MIDI data can be stored in the block as well. As
more instruments come to market, they will likely have parameters that have
not been included in the AIFF-C specification. The MIDI System Exclusive
messages for these instruments may contain many parameters that are not
included in the Instrument Chunk. For example, a new sampling instrument
may have more than the two loops defined in the Instrument Chunk. These
loops will likely be represented in the MIDI System Exclusive message for
the new machine. This MIDI System Exclusive message can be stored in the
MIDI Data Chunk.
ckID 4 Bytes The ID for this chunk. These four bytes must be "MIDI."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
MIDIdata Unsigned Bytes A stream of MIDI Data. If the length of the
MIDI data is odd, a pad byte must follow it to make it even.
The MIDI Data Chunk is optional. Any number of MIDI Data Chunks may exist
in a FORM AIFC. If MIDI System Exclusive messages for several instruments
are to be stored in a FORM AIFC, it is better to use one MIDI Data
Chunk per instrument than one big MIDI Data Chunk for all of the instruments.
The Audio Recording Chunk
The Audio Recording Chunk contains information pertinent to audio recording
devices.
ckID 4 Bytes The ID for this chunk. These four bytes must be "AESD."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
For the Audio Recording Chunk, this value is always 24.
AESChannelStatusData 24 Bytes These 24 bytes are specified in the
AES Recommended Practice for Digital Audio Engineering--Serial Transmission
Format for Linearly Represented Digital Audio Data, section 7.1, Channel
Status Data. This document describes a format for real-time digital transmission
of digital audio between audio devices. This information is duplicated in
the Audio Recording Chunk for convenience. Bits 2, 3, and 4 of byte zero
are of general interest as they describe recording emphasis.
The Audio Recording Chunk is optional. No more than one Audio Recording
Chunk may appear in a FORM AIFC.
The Application Specific Chunk
The Application Specific Chunk can be used for any purposes whatsoever by
developers and application authors. For example, an application that edits
sounds might want to use this chunk to store editor state parameters such
as magnification levels, last cursor position, etc.
ckID 4 Bytes The ID for this chunk. These four bytes must be "APPL."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
For the Audio Recording Chunk, this value is always 24.
OSType 4 Bytes Identifies a particular application. For Apple II
applications, these four bytes should always be `pdos' ($70 $64
$6F $73). For non-Apple applications, these four bytes should be `stoc'.
In these cases, the beginning of the data area is defined to be a Pascal
string containing the name of the application. For Macintosh applications,
this is simply the four-character signature as registered with Developer
Technical Support.
AppSignature String Pascal string identifying the application.
data Bytes Data specific to the application.
Note: AppSignature does not exist unless OSType is "pdos"
or "stoc". In all other cases, the data area starts immediately
following the OSType field.
Be sure to plan for the future when defining the data section of your Application
Specific Chunk. Use a version numbering scheme or other appropriate method
that will enable the current and future versions of your applications to
interpret the data in the FORM AIFC. Specifically, the
current application should be able to inform the user when a new version
is encountered which it cannot handle (and possibly even prompt the user
with a solution). Future applications should be able to handle older versions
of the data or guide the user to a solution.
The Application Specific Chunk is optional. Any number of Application Specific
Chunks may exist in a single FORM AIFC.
The Comments Chunk
The Comments Chunk is used to store comments in the FORM AIFC.
"EA IFF 85" has an Annotation Chunk (used in ASIF) that can be
used for comments, but the Comments Chunk has two features not found in
the "EA IFF 85" chunk. They are a time-stamp for the comment and
a link to a marker.
ckID 4 Bytes The ID for this chunk. These four bytes must be "COMT."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
numComments Rev. Unsigned Word The number of comments in the Comments
Chunk. This is followed by the comments themselves. Comments are always
an even number of bytes in length, so there is no padding between comments
in the Comments Chunk.
Comment Comment The comments. There are numComments of them.
The format of a comment is described below:
timeStamp Rev. Unsigned Long Indicates when the comment was created.
Units are the number of seconds since 12:00 a.m. (midnight), January 1,
1904. This is the standard Macintosh time format. Macintosh routines to
manipulate this time stamp may be found in Inside Macintosh, Volume
II.
Note: Apple IIGS System Software 5.0.3 and later contains a Miscellaneous
Tools routine, ConvSeconds, which can convert times in the format
of timeStamp into standard ProDOS, GS/OS or HyperCard IIGS dates.
marker Rev. Word A Marker ID. If this comment is linked to a marker
(to store a long description of a marker as a comment, for example), this
is the ID of that marker. Otherwise marker is zero, indicating there is
no such link.
count Rev. Word Count of the number of characters in the following
text. By using a word instead of a byte, much larger comments may be created.
text Bytes The comment itself. If the text is an odd number of bytes
in length, it must be padded with a zero byte to ensure that it is an even
number of bytes in length. If the pad byte is present, it is not included
in count.
The Comments Chunk is optional. No more than one Comments Chunk may appear
in a single FORM AIFC.
The Text Chunks
These four chunks are included in the definition of every "EA IFF 85"
file. All are text chunks; their data portion consists solely of text. Each
of these chunks is optional.
The Name Chunk
This chunk names the sampled sound.
ckID 4 Bytes The ID for this chunk. These four bytes must be "NAME."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
Name Bytes ASCII characters ($20-$7F) representing the name. There
should be ckSize characters.
No more than one Name Chunk may exist within a FORM AIFC.
The Author Chunk
This chunk can be used to identify the creator of a sampled sound.
ckID 4 Bytes The ID for this chunk. These four bytes must be "AUTH."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
author Bytes ASCII characters ($20-$7F) representing the name of
the author of the sampled sound. There should be ckSize characters.
No more than one Author Chunk may exist within a FORM AIFC.
The Copyright Chunk
The Copyright Chunk contains a copyright notice for the sound. The copyright
contains a date followed by the copyright owner. The chunk ID "(c)
" serves as the copyright character ((c)). For example, a Copyright
Chunk containing the text "1989 Apple Computer, Inc." means "(c)
1989 Apple Computer, Inc."
ckID 4 Bytes The ID for this chunk. These four bytes must be "(c)
."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
You may think of this value as the offset to the end of the chunk.
notice Bytes ASCII characters ($20-$7F) representing a copyright
notice for the voice or collection of voices. There should be ckSize characters.
No more than one Copyright Chunk may exist within a FORM AIFC.
The Annotation Chunk
Use of this comment is discouraged within FORM AIFC. The more powerful
Comments Chunk should be used instead.
ckID 4 Bytes The ID for this chunk. These four bytes must be "ANNO."
ckSize Rev. Long The length of this chunk, excluding ckSize and cdID.
You may think of this value as the offset to the end of the chunk. Note
that this is a Reverse Long; the bytes are stored high byte first.
author Bytes ASCII characters ($20-$7F) representing the name of
the author of the voices or collection of voices. There should be ckSize
characters.
Many Annotation Chunks may exist within a FORM AIFC.
Chunk Precedence
Several of the local chunks for FORM AIFC may contain duplicate
information. For example, the Instrument Chunk defines loop points and MIDI
System Exclusive data in the MIDI Data Chunk may also define loop points.
What happens if these loop points are different? How is an application supposed
to loop the sound? Such conflicts are resolved by defining a precedence
for chunks. This precedence is listed in Table 2.
Format Version Chunk Highest precedence
Common Chunk
Instrument Chunk
Saxel Chunk
Comments Chunk
Marker Chunk
Sound Data Chunk
Name Chunk
Author Chunk
Copyright Chunk
Annotation Chunk(s) --in the order they appear in the FORM
Audio Recording Chunk
MIDI Data Chunk(s)
Application Specific Chunks Lowest precedence
Table 2-Chunk Precedence
The Format Version Chunk has the highest precedence, while the Application
Specific Chunk has the lowest. Information in the Common Chunk always takes
precedence over conflicting information in any other chunk. The Application
Specific Chunk always loses in conflicts with other chunks. By looking at
the chunk hierarchy, for example, one sees that the loop points in the Instrument
Chunk take precedence over conflicting loop points found in the MIDI Data
Chunk.
It is the responsibility of applications that write data into the lower
precedence chunks to make sure that the higher precedence chunks are updated
accordingly.
AIFF-C Examples
Illustrated below are examples of several FORM AIFC files.
An AIFF-C file is simply a file containing a single FORM AIFC.
These examples have been designed to illustrate several of the possible
variations of sound data and Chunk formats you may encounter. A careful
study of these examples will clarify the Chunk specifications. Remember
that the Chunks may appear in any order in a FORM AIFC--the
order shown here is only for the sake of the examples.
Example 1--A file containing approximately 4.476 seconds of 8-bit monophonic
uncompressed sound data sampled at 22.25454 KHz:

Figure 14-Sample FORM AIFC #1
Example 2--A file containing approximately 28.972 seconds of 8-bit sound
data sampled at 22.25454 and compressed by a factor of 2 using the Apple
IIGS Audio Compression and Expansion tool.

Figure 15-Sample FORM AIFC #2
Example 3--A file containing approximately 2.325 seconds of 16-bit stereo
uncompressed sound data sampled at 44.1 KHz (CD quality).

Figure 16-Sample FORM AIFC #3
Further Reference
* Apple Numerics Manual, Second Edition
* File Type Note File Type $D8, Auxiliary Type $0000, Audio Interchange
File Format
* File Type Note File Type $D8, Auxiliary Type $0002, Apple IIGS Sampled
Instrument Format
* Audio Interchange File Format v1.3 (APDA)
* AES Recommended Practice for Digital Audio Engineering--Serial Transmission
Format for Linearly Represented Digital Audio Data, Audio Engineering
Society, 60 East 42nd Street, New York, NY 10165
* MIDI: Musical Instrument Digital Interface, Specification 1.0,
the International MIDI Association.
* "EA IFF 85" Standard for Interchange Format Files (Electronic
Arts)
* "8SVX" IFF 8-bit Sampled Voice (Electronic Arts)