Stephen Travis Pope and Guido van Rossum
Computer Music Journal, Vol:l9, No:1, Spring 1995
© Massachusetts Institute of Technology.


AIFF and AIFC Formats

The interchange file format (IFF) was developed by Electronic Arts, Inc. and extended to the standard IFF/8VSX by them, and then to audio IFF (AIFF) by Apple Computer, Inc. for storing high-resolution sound and MIDI instrument info (Electronic Arts 1985; Apple 1989). It is also used by Silicon Graphics, Inc. and several professional audio packages on various platforms. An extension, called AIFF-C or AIFC, supports several data-compression schemes (see below). A version of the full AIFF/C specification (Apple 1989) is available from several Internet ftp sites, including ftp.cwi.nl:/pub/audio/AudioIFFl.3.hqx (a BinHex'ed MS-Word file); mitpress.mit.edu:/pub/Computer-Music-Journal/Documents/SoundFiles/AIFF-C.ps.Z (compressed PostScript); and ftp.sgi.com:/aiff-c.9.26.91.ps (PostScript). It can also be found in Milne and Deatherage (l991). The IFF standard is available in Electronic Arts (1985).
Like its relatives IFF and TIFF, AIFF is a "chunked" file format. Chunked files have a flexible format, rather than a fixed header followed by a single data block. There is a small (12-byte) fixed file header, followed by a variable number of data or other "chunk" blocks, in any order. Each chunk starts with a header that has a "type" field (a key or chunk ID-to identify the format of its contents), and a "size" word giving the size of its data (normally in bytes). Sample files in AIFF have a "common" chunk (with the same information as a typical sound file header!, one or more chunks describing cue points, text comments, copyright information, sampler setup information, or MIDI data, and one sound-data chunk. The common chunk normally comes after the fixed header, followed by the other chunks, with the sample-data chunk last, though one can write other chunks after the sample data if desired.

Figure 3: Minimal AIFF File Structure

Form Chunk
Chunk ID = "FORM"
File size (all chunks)
Form Type = "AIFP"
Common Chunk
Chunk ID = "COMM"
Common chunk data size
Sample format, rate, etc.
Data Chunk
Chunk ID = "SSND"
Sound chunk data size
Array of sample data

Figure 3 illustrates how an AIFF file is constructed. It starts with a header or "form" chunk that includes the file's magic number (the 32-bit quantity representing the four-character string "FORM"). There is a common chunk that defines the sound-sample data format, and one sound-data chunk (though they need not be in the order shown).
The rest of the file format is flexible and depends on the application that created the file. No more than one sample data chunk is allowed in a file, but any number of cue, text, and other kinds chunks can be used to annotate AIFF sounds. The IFF definition allows for amplitude-contour chunks (e.g., attack or decay), and IFF files includ four standard annotations: author, name, annotation, and copyright strings. Three chunk types greatly empower AIFF applications: sampler instrument data, raw MIDI data, and application specific chunks. These will be discussed below.
The C-language data structures common to all AIFF chunks is shown in Figure 4. Every chunk starts with its type ID (32-bits representing an ASCII string of four letters)and 32-bit chunk size.
Note the macros for unsigned data types in Figur 4, as well as the use of 80-bit extended-precision floating-point numbers (which are required by th API implementor). The Pascal-style string type i character array preceded by its length (rather the being null-terminated as in C). This has the advantage of being faster to skip over without having to scan for length.

Figure 4. Basic AIFF declarations and chunk structure.

* Type definitions used in AIFF structures */
typedef char[4] ID;	/* Magic numbers are 4-char IDs */
typedef unsigned long VLong;	/* Used for large numbers */
typedef extended float XFloat;	/* 80-bit floats for sample rates */
typedef unsigned char UChar;	/* Used for raw data pointers */
typedef unsigned short UShort;	/* Used for long counters */
typedef short MarkerId;	/* Used for marker numbers */

	/* AIFF uses Pascal-style strings with their lengths prepended. */
typedef struct {
	UChar ckSize;	/* String length in Bytes (<= 255) */
	char ckData[];	/* String data (not null-terminated */
} PString;

	/* General AIFF chunk structure */
typedef struct {
	ID ckID;	/* Chunk ID string, 32-bits = 4 characters */
	long ckSize;	/* Chunk data size in Bytes */
	char ckData[];	/* Chunk data-format varies according to type */
} Chunk;

The form header that is included at the beginning of all AIFF files is shown in Figure 5. The first ID identifies the file as some kind of IFF chunked file, the second gives the "local" format-AIFF or AIFC. The rest of the chunk data (ckSize bytes) follows this header.

Figure 5. AIFF form chunk structure.

/* AIFF/C Chunk-Global File "Wrapper */
typedef struct {
	ID	ckID;	/* ID = "FORM" */
	long	ckSize	/* Size of file's Chunk in bytes */
	ID	formType	/* ID = "AIFF" or "AIFC" */
	char	chunks [];	/* 1 or more chunks in any order */
} FORM_Header;

The AIFF common chunk corresponds to the sound file header of the formats described above. Its fields include the sample rate, sample format and precision, the number of channels, and the size of the sample data block. As shown in Figure 6, the chunk header is followed by these fields, using an integer to store the sample size in bits (824) of (assumed linear integer) samples, and an 80-bit float for the sample rate.

Figure 6. AIFF common data chunk.

/* AIFF/C Common Data Chgunk-Sound Data Properties */
typedef struct {
	ID	ckID;	/* = "COMM" */
	long	ckSize	/* = 18 Bytes in chunk */
	short	numChannels;	/* 1, 2, or more */
	Ulong	numSampleFrames;	/* number of full frames */
	short	sampleSize	/* size in bits/sample */
	XFloat	sampleRate;	/* rate as an 80-bit float */
} CommonChunk;

One sound data chunk is allowed per AIFF file; its format is defined in Figure 7, which shows the standard chunk header and variable-type sample data array. The offset and block size are normally 0, but can be used to indicate silence at the beginning of a sound or to optimize data buffering.

Figure 7. AIFF sound sample data chunk.

/* AIFF/C Data Structure for marker points */
typedef struct {
	MarkerId	id;	/* Marker number */
	Ulong	position;	/* Sample offset */
	PString	markerName;	/* Name String */
} Marker;

The other chunks that AIFF supports allow one to define named markers that point into a file's sample data, to add several kinds of comments to the file, or to attach a special data structure with MIDI instrument voicing data for a sampler. The data structure used for markers or cue points is defined in Figure 8, followed by the format for marker chunks. Note that a single marker chunk can hold many named markers.

Figure 8. AIFF marker structure and chunk.

/* Marker chunk with array of markers */
typedef struct {
	ID	ckID;	/* = "MARK" */
	long	ckSize;	/* Size of data Bytes */
	Ushort	numMarkers;	/* How many markers in chunk */
	Marker	Markers [];	/* Marker data structure */
} MarkerChunk;

One or more comment strings-that also keep a time-stamp and can be "associated" with a specific marker ID-can be encapsulated in a special comments chunk. The two data structures for this are defined in Figure 9. Note that this chunk type is only used for uninterpreted comments; other chunk types exist for specific annotations such as author, copyright, etc. (see below).

Figure 9. AIFF comment structure and chunk.

/* AIFF/C Comment Data Structurc with Marker ID and time-stamp */
typedef struct {
	ULong timeStamp;	/* When was comment created */
				/* (in sec since 1/1/1904) */
	MarkerID	marker;	/* Optional marker comment applies to */
	UShort	count;	/* Size in Bytes of text */
	char	text[];	/* Comment string */
} Comment;

/* Comments Chunk-can hold onto many comments */
typedef struct {
	ID	ckID; /* = "COMT~ */
	long	ckSize; /* Size of data in Bytes */
	UShort	numComm; /* How many comment records */
	Comment	comments[]; /* Array of comments */
} CommentsChunk;

The MIDI voice information mentioned above is stored in an instrument chunk, shown in Figure 10. It has fields for the "true" frequency of the sample (as a MIDI key number with de-tuning in cents), and the suggested high and low transposition range (as key numbers) and dynamics (as MIDI key velocities) of the sample. The default gain is a dB value by which to scale the sample to achieve full amplitude, which is very useful.

Figure 10. AIFF loop structure and MIDI instrument chunk.

/* AIFF/C Loop data structure-uses numerical marker IDs */
typedef struct {
	short	playMode; /* Loop play mode */
	MarkerId	beginLoop; /* Cue marker where loop starts */
	MarkerId endLoop; /* Cue marker where loop ends */
} Loop;

/* MIDI Instrument Data Chunk-sampler voicing */
typedef struct {
	ID ckID;	/* = "INSTn */
	long ckSize;	/* = 20 Bytes */
	char baseNote;	/* Frequency of sample as a MIDI Key */
	char detune;	/* Fine-tuning in Cent */
	char lowNote;	/* Lowest note to transpose sample to */
	char highNote;	/* Highest note to transpose sample to */
	char lowVelocity;	/* Lowest velocity to play sample at */
	char highVelocity;	/* Highest velocity to play sample at */
	short gain;	/* Default gain in dB */
	Loop sustainLoop;	/* Optional sustain loop record */
	Loop releaseLoop;	/* Optional release (decay) loop record */
} InstrumentChunk;

An instrument chunk can also define how sample is to be extended in length if it is sustained beyond its stored duration. Begin and end points can be given for a section of the "steady-state" portion of the sample, so that a sampling synthesizer can "loop" through it, repeating it as necessary be fore playing the "release" or "decay" portion of the sample. The data structure for loops is defined in Figure 10; it refers to two marker IDs (by number) assumed to be defined in a marker chunk.
Other chunk types are defined to support storing uninterpreted "raw" MIDI data, AES (Audio Engineering Society) channel data for live recordings (e.g., emphasis information), four kinds of text annotation (name, author, copyright, and annotation) (AES 1990), and free-form "application-specific" data.
AIFC defines header formats for µ- and A-law, ADPCM, and other compression schemes.


[ Index | Main Paragraph | Previous Paragraph | Next Paragraph ]