Copyright (c) Hyperion Entertainment and contributors.
Difference between revisions of "AIFF IFF Audio Samples"
Jump to navigation
Jump to search
Steven Solie (talk | contribs) (→AIFF) |
Steven Solie (talk | contribs) (Replaced content with "=== AIFF === The AIFF standard is controlled by Apple Inc. AIFF Standard 1.3 (PDF)") |
||
Line 1: | Line 1: | ||
=== AIFF === |
=== AIFF === |
||
+ | The AIFF standard is controlled by Apple Inc. |
||
− | [[File:AIFF_1.3.pdf]]. |
||
+ | [[Media:AIFF-1.3.pdf|AIFF Standard 1.3 (PDF)]] |
||
− | <pre> |
||
− | Audio 1-32 bit samples (Mac,AppleII,Synthia Pro) |
||
− | |||
− | provided by Steve Milne and Matt Deatherage, Apple Computer, Inc. |
||
− | |||
− | AIFF: Audio Interchange File Format File |
||
− | ---------------------------------------- |
||
− | |||
− | 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. |
||
− | |||
− | Audio IFF conforms to the "`EA IFF 85' Standard for Interchange Format Files" |
||
− | developed by Electronic Arts. |
||
− | |||
− | Audio IFF is primarily an interchange format, although 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. |
||
− | |||
− | Audio IFF is the result of several meetings held with music developers over a |
||
− | period of ten months during 1987 and 1988. 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. Audio |
||
− | IFF is intended for use with a larger variety of computers, sampled sound |
||
− | instruments, sound software applications, and high fidelity recording devices. |
||
− | |||
− | Data Types |
||
− | |||
− | A C-like language will be used to describe the data structures in this document |
||
− | The data types used are listed below. |
||
− | |||
− | char: 8 bits signed. A char can contain more than just ASCII |
||
− | characters. It can contain any number from -128 to 127 |
||
− | (inclusive). |
||
− | unsigned char: 8 bits signed. Contains any number from 0 to 255 (inclusive). |
||
− | short: 16 bits signed. Contains any number from -32,768 to 32,767 |
||
− | (inclusive). |
||
− | unsigned short: 16 bits unsigned. Contains any number from 0 to 65,535 |
||
− | (inclusive). |
||
− | long: 32 bits signed. Contains any number from -2,147,483,648 |
||
− | to 2,147,483,647 (inclusive). |
||
− | unsigned long: 32 bits unsigned. Contains any number from 0 to |
||
− | 4,294,967,295 (inclusive). |
||
− | extended: 80 bit IEEE Standard 754 floating point number (Standard |
||
− | Apple Numeric Environment [SANE] data type Extended) |
||
− | pstring: Pascal-style string, a one-byte count followed by text |
||
− | bytes. The total number of bytes in this data type should |
||
− | be even. A pad byte can be added to the end of the text to |
||
− | accomplish this. This pad byte is not reflected in the |
||
− | count. |
||
− | ID: 32 bits, the concatenation of four printable ASCII characters |
||
− | in the range " " (space, 0x20) through "~" (tilde, 0x7E). |
||
− | Leading spaces are not allowed in the ID but trailing spaces |
||
− | are OK. Control characters are forbidden. |
||
− | |||
− | |||
− | Constants |
||
− | |||
− | Decimal values are referred to as a string of digits, for example 123, 0, 100 |
||
− | are all decimal numbers. Hexadecimal values are preceded by a 0x - e.g., 0x0A, |
||
− | 0x1, 0x64. |
||
− | |||
− | Data Organization |
||
− | |||
− | All data is stored in Motorola 68000 format. The bytes of multiple-byte |
||
− | values are stored with the high-order bytes first. Data is organized as |
||
− | follows: |
||
− | |||
− | 7 6 5 4 3 2 1 0 |
||
− | +-----------------------+ |
||
− | char: | msb lsb | |
||
− | +-----------------------+ |
||
− | |||
− | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
||
− | +-----------------------+-----------------------+ |
||
− | char: | msb byte 0 | byte 1 lsb | |
||
− | +-----------------------+-----------------------+ |
||
− | |||
− | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
||
− | +-----------------------+-----------------------+ |
||
− | char: | msb byte 0 | byte 1 | |
||
− | +-----------------------+-----------------------+ |
||
− | char: | byte 2 | byte 3 lsb | |
||
− | +-----------------------+-----------------------+ |
||
− | |||
− | Figure 1: IFF data storage formats |
||
− | |||
− | Referring to Audio IFF |
||
− | |||
− | The official name for this standard is Audio Interchange File Format. 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. |
||
− | Referring to Audio IFF files by a four-letter abbreviation (i.e., "AIFF") in |
||
− | user-level documentation or program-generated messages should be avoided. |
||
− | |||
− | |||
− | File Structure |
||
− | |||
− | The "`EA IFF 85' Standard for Interchange Format Files" defines an overall |
||
− | structure for storing data in files. Audio IFF conforms to those portions |
||
− | of "EA IFF 85" that are germane to Audio IFF. For a more complete discussion |
||
− | of "EA IFF 85", please refer to the document "`EAIFF 85', Standard for |
||
− | Interchange Format Files." |
||
− | |||
− | An "EA IFF 85" file is made up of a number of chunks of data. Chunks are the |
||
− | building blocks of "EA IFF 85" files. A chunk consists of some header |
||
− | information followed by data: |
||
− | |||
− | +--------------------+ |
||
− | | ckID |\ |
||
− | +--------------------+ } header info |
||
− | | ckSize |/ |
||
− | +--------------------+ |
||
− | | | |
||
− | | | |
||
− | | data | |
||
− | | | |
||
− | | | |
||
− | +--------------------+ |
||
− | |||
− | Figure 2: IFF Chunk structure |
||
− | |||
− | A chunk can be represented using our C-like language in the following manner: |
||
− | |||
− | typedef struct { |
||
− | ID ckID; /* chunk ID */ |
||
− | long ckSize; /* chunk Size */ |
||
− | |||
− | char ckData[]; /* data */ |
||
− | } Chunk; |
||
− | |||
− | The ckID describes the format of the data portion of a chunk. A program can |
||
− | determine how to interpret the chunk data by examining ckID. |
||
− | |||
− | The ckSize is the size of the data portion of the chunk, in bytes. It does |
||
− | not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The ckData contains the data stored in the chunk. The format of this data is |
||
− | determined by ckID. If the data is an odd number of bytes in length, a zero pad |
||
− | byte must be added at the end. The pad byte is not included in ckSize. |
||
− | |||
− | Note that an array with no size specification (e.g., char ckData[];) indicates a |
||
− | variable-sized array in our C-like language. This differs from standard C. |
||
− | |||
− | An Audio IFF 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 later sections of this document. |
||
− | |||
− | The chunks in an Audio IFF 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 Audio IFF is called a FORM. A FORM has |
||
− | the following format: |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | ID formType; |
||
− | char chunks[]; |
||
− | } |
||
− | |||
− | The ckID is always 'FORM'. This indicates that this is a FORM chunk. |
||
− | |||
− | The ckSize contains the size of data portion of the 'FORM' chunk. Note that |
||
− | the data portion has been broken into two parts, formType and chunks[]. |
||
− | |||
− | The formType field describes what's in the 'FORM' chunk. For Audio IFF files, |
||
− | formType is always 'AIFF'. This indicates that the chunks within the FORM |
||
− | pertain to sampled sound. A FORM chunk of formType 'AIFF' is called a FORM |
||
− | AIFF. |
||
− | |||
− | The chunks field are the chunks contained within the FORM. These chunks are |
||
− | called local chunks. A FORM AIFF along with its local chunks make up an |
||
− | Audio IFF file. |
||
− | |||
− | Here is an example of a simple Audio IFF file. It consists of a file containing |
||
− | single FORM AIFF which contains two local chunks, a Common Chunk and a Sound |
||
− | Data Chunk. |
||
− | |||
− | __________________________ |
||
− | | FORM AIFF Chunk | |
||
− | | ckID = 'FORM' | |
||
− | | formType = 'AIFF' | |
||
− | | __________________ | |
||
− | | | Common Chunk | | |
||
− | | | ckID = 'COMM' | | |
||
− | | |__________________| | |
||
− | | __________________ | |
||
− | | | Sound Data Chunk | | |
||
− | | | ckID = 'SSND' | | |
||
− | | |__________________| | |
||
− | |__________________________| |
||
− | |||
− | Figure 3: Simple Audio IFF File |
||
− | |||
− | There are no restrictions on the ordering of local chunks within a FORM AIFF. |
||
− | |||
− | A more detailed example of an Audio IFF file can be found in Appendix A. Please |
||
− | refer to this example as often as necessary while reading the remainder of this |
||
− | document. |
||
− | |||
− | |||
− | Storage of AIFF on Apple and Other Platforms |
||
− | |||
− | On a Macintosh, the FORM AIFF, is stored in the data fork of an Audio IFF file. |
||
− | The Macintosh file type of an Audio IFF file is 'AIFF'. This is the same as |
||
− | the formType of the FORM AIFF. Macintosh applications should not store any |
||
− | information in Audio IFF file's resource fork, as this information may not be |
||
− | preserved by all applications. Applications can use the Application Specific |
||
− | Chunk, defined later in this document, to store extra information specific to |
||
− | their application. |
||
− | |||
− | Audio IFF files may be identified in other Apple file systems as well. On a |
||
− | Macintosh under MFS or HFS, the FORM AIFF is stored in the data fork of a file |
||
− | with file type "AIFF." This is the same as the formType of the FORM AIFF. |
||
− | |||
− | On an operating system such as MS-DOS or UNIX, where it is customary to use a |
||
− | file name extension, it is recommended that Audio IFF file names use ".AIF" |
||
− | for the extension. |
||
− | |||
− | On an Apple II, FORM AIFF is stored in a file with file type $D8 and auxiliary |
||
− | type $0000. Versions 1.2 and earlier of the Audio IFF standard used file type |
||
− | $CB and auxiliary type $0000. This is incorrect; the assignment listed in |
||
− | this document is the correct assignment. |
||
− | |||
− | On the Apple IIGS stereo data is stored with right data on even channels and |
||
− | left data on odd channels. Some portions of AIFF do not follow this |
||
− | convention. Even where it does follow the convention, AIFF usually uses |
||
− | channel two for right data instead of channel zero as most Apple IIGS |
||
− | standards do. Be prepared to interpret data accordingly. |
||
− | |||
− | |||
− | Local Chunk Types |
||
− | |||
− | The formats of the different local chunk types found within a FORM AIFF 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 AIFF must be able to read the required chunks and can choose to |
||
− | selectively ignore the optional chunks. A program that copies a FORM AIFF |
||
− | should copy all the chunks in the FORM AIFF, even those it chooses not to |
||
− | interpret. |
||
− | |||
− | |||
− | The Common Chunk |
||
− | |||
− | The Common Chunk describes fundamental parameters of the sampled sound. |
||
− | |||
− | #define CommonID 'COMM' /* ckID for Common Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | short numChannels; |
||
− | unsigned long numSampleFrames; |
||
− | short sampleSize; |
||
− | extended sampleRate; |
||
− | } CommonChunk; |
||
− | |||
− | The ckID is always 'COMM'. The ckSize is the size of the data portion of the |
||
− | chunk, in bytes. It does not include the 8 bytes used by ckID and ckSize. |
||
− | For the Common Chunk, ckSize is always 18. |
||
− | |||
− | The numChannels field contains the number of audio channels for the sound. |
||
− | A value of 1 means monophonic sound, 2 means stereo, and 4 means four channel |
||
− | sound, etc. Any number of 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. |
||
− | |||
− | The actual sound samples are stored in another chunk, the Sound Data Chunk, |
||
− | which will be described shortly. |
||
− | |||
− | 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. |
||
− | |||
− | The numSampleFrames field contains the number of sample frames. This is not |
||
− | necessarily the same as the number of bytes nor the number of samplepoints in |
||
− | the Sound Data Chunk. The total number of sample points in the file is |
||
− | numSampleFrames times numChannels. |
||
− | |||
− | The sampleSize is the number of bits in each sample point. It can be any |
||
− | number from 1 to 32. The format of a sample point will be described in the |
||
− | next section. |
||
− | |||
− | The sampleRate field is the sample rate at which the sound is to be played |
||
− | back in sample frames per second. |
||
− | |||
− | One, and only one, Common Chunk is required in every FORM AIFF. |
||
− | |||
− | |||
− | Sound Data Chunk |
||
− | |||
− | The Sound Data Chunk contains the actual sample frames. |
||
− | |||
− | #define SoundDataID 'SSND' /* ckID for Sound Data Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | unsigned long offset; |
||
− | unsigned long blockSize; |
||
− | unsigned char SoundData []; |
||
− | } SoundDataChunk; |
||
− | |||
− | The ckID is always 'SSND'. The ckSize is the size of the data portion of the |
||
− | chunk, in bytes. It does not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The offset field determines where the first sample frame in the soundData |
||
− | 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 the |
||
− | Block-Aligning Sound Data section below. |
||
− | |||
− | The blockSize is used in conjunction with offset for block-aligning sound |
||
− | data. It contains the size in bytes of the blocks that sound 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 the Block-Aligning Sound Data |
||
− | section below. |
||
− | |||
− | The soundData field contains the sample frames that make up the sound. The |
||
− | number of sample frames in the soundData is determined by the numSampleFrames |
||
− | field in the Common Chunk. Sample points and sample frames are explained in |
||
− | detail in the next section. |
||
− | |||
− | 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 |
||
− | AIFF. |
||
− | |||
− | |||
− | Sample Points and Sample Frames |
||
− | |||
− | A large part of interpreting Audio IFF files revolves around the two concepts |
||
− | of sample points and sample frames. |
||
− | |||
− | A sample point is a value representing a sample of a sound at a given point in |
||
− | time. Each sample point is stored as a linear, 2's-complement value which 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 4. A 12-bit |
||
− | sample point, binary 101000010111, is stored left justified in two bytes. |
||
− | The remaining bits are set to zero. |
||
− | |||
− | ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |
||
− | | | | | | | | | | | | | | | | | | |
||
− | | 1 0 1 0 0 0 0 1 | 0 1 1 1 0 0 0 0 | |
||
− | |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___| |
||
− | <---------------------------------------------> <-------------> |
||
− | 12 bit sample point is left justified rightmost |
||
− | 4 bits are |
||
− | zero padded |
||
− | Figure 4: 12-Bit Sample Point |
||
− | |||
− | |||
− | For multichannel sounds, single sample points from each channel are |
||
− | interleaved. A set of interleaved sample points is called a sample frame. |
||
− | 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 5 for the stereo (two channel) case. |
||
− | |||
− | sample sample sample |
||
− | frame 0 frame 1 frame N |
||
− | _____ _____ _____ _____ _____ _____ |
||
− | | ch1 | ch2 | ch1 | ch2 | . . . | ch1 | ch2 | |
||
− | |_____|_____|_____|_____| |_____|_____| |
||
− | _____ |
||
− | | | = one sample point |
||
− | |_____| |
||
− | |||
− | Figure 5: 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 6. |
||
− | |||
− | channel |
||
− | 1 2 3 4 5 6 |
||
− | _________ _________ _________ _________ _________ _________ |
||
− | | left | right | | | | | |
||
− | stereo | | | | | | | |
||
− | |_________|_________|_________|_________|_________|_________| |
||
− | | left | right | center | | | | |
||
− | 3 channel | | | | | | | |
||
− | |_________|_________|_________|_________|_________|_________| |
||
− | | front | front | rear | rear | | | |
||
− | quad | left | right | left | right | | | |
||
− | |_________|_________|_________|_________|_________|_________| |
||
− | | left | center | right | surround| | | |
||
− | 4 channel | | | | | | | |
||
− | |_________|_________|_________|_________|_________|_________| |
||
− | | left | left | center | right | right |surround | |
||
− | 6 channel | | center | | | center | | |
||
− | |_________|_________|_________|_________|_________|_________| |
||
− | |||
− | Figure 6: Sample Frame Conventions for Multichannel Sound |
||
− | |||
− | 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. |
||
− | |||
− | |||
− | 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 7. |
||
− | |||
− | ____________ __________________________________ ____________ |
||
− | |\\ unused \\| sample frames |\\ unused \\| |
||
− | |____________|__________________________________|____________| |
||
− | <-- offset --><- numSampleFrames sample frames -> |
||
− | |||
− | | blockSize | | | | |
||
− | |<- bytes ->| | | | |
||
− | |_______________|_______________|_______________|_______________| |
||
− | block N-1 block N block N+1 block N+2 |
||
− | |||
− | Figure 7: Block-Aligned Sound Data |
||
− | |||
− | In Figure 7, 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 Audio IFF |
||
− | files. Applications that write block-aligned sound data should set blockSize |
||
− | to the appropriate block size. Applications that modify an existing Audio IFF |
||
− | 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. |
||
− | |||
− | Markers |
||
− | |||
− | A marker has the following format. |
||
− | |||
− | typedef short MarkerId; |
||
− | |||
− | typedef struct { |
||
− | MarkerID id; |
||
− | unsigned long position; |
||
− | pstring markerName; |
||
− | } Marker; |
||
− | |||
− | The id is a number that uniquely identifies that marker within a FORM 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. |
||
− | |||
− | The marker's position in the sound data is determined by the position field. |
||
− | 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 1. Note that the units for position are sample frames, not |
||
− | bytes nor sample points. |
||
− | |||
− | Sample Frames |
||
− | ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |
||
− | | | | | | | | | | | | | | |
||
− | |___|___|___|___|___|___|___|___|___|___|___|___| |
||
− | ^ ^ ^ |
||
− | position 0 position 5 position 12 |
||
− | |||
− | Figure 8: Sample Frame Marker Positions |
||
− | |||
− | |||
− | The markerName field is a Pascal-style text string containing the name of the |
||
− | mark. |
||
− | |||
− | Note: Some "EA IFF 85" files store strings a 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. |
||
− | |||
− | |||
− | Marker Chunk Format |
||
− | |||
− | The format for the data within a Marker Chunk is shown below. |
||
− | |||
− | #define MarkerID 'MARK' /* ckID for Marker Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | unsigned short numMarkers; |
||
− | Marker Markers []; |
||
− | } MarkerChunk; |
||
− | |||
− | The ckID is always 'MARK'. The ckSize is the size of the data portion of the |
||
− | chunk in bytes. It does not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The numMarkers field is the number of markers in the Marker Chunk. If |
||
− | numMarkers is non-zero, it 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. The markers need not be ordered in any particular manner. |
||
− | |||
− | The Marker Chunk is optional. No more than one Marker Chunk can appear in a |
||
− | FORM AIFF. |
||
− | |||
− | |||
− | The Instrument Chunk |
||
− | |||
− | The Instrument Chunk defines basic parameters that an instrument, such as a |
||
− | sample, could use to play the sound data. |
||
− | |||
− | Looping |
||
− | |||
− | Sound data can be looped, allowing a portion of the sound to be repeated in |
||
− | order to lengthen the sound. The structure below describes a loop. |
||
− | |||
− | typedef struct { |
||
− | short PlayMode; |
||
− | MarkerId beginLoop; |
||
− | MarkerId endLoop; |
||
− | } Loop; |
||
− | |||
− | 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. |
||
− | |||
− | ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ |
||
− | sample frames | | | |<--- loop segment ---->| | | | |
||
− | |___|___|___|___|___|___|___|___|___|___|___|___| |
||
− | ^ ^ |
||
− | begin position end position |
||
− | |||
− | Figure 9: 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. |
||
− | |||
− | The playMode specifies which type of looping is to be performed: |
||
− | |||
− | #define NoLooping 0 |
||
− | #define ForwardLooping 1 |
||
− | #define ForwardBackwardLooping 2 |
||
− | |||
− | If NoLooping is specified, then the loop points are ignored during playback. |
||
− | |||
− | The beginLoop is a marker id that marks the begin position of the loop segment. |
||
− | |||
− | 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 zero or negative length and no looping takes place. |
||
− | |||
− | |||
− | The Instrument Chunk Format |
||
− | |||
− | The format of the data within an Instrument Chunk is described below. |
||
− | |||
− | #define InstrumentID 'INST' /*ckID for Instruments Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | char baseNote; |
||
− | char detune; |
||
− | char lowNote; |
||
− | char highNote; |
||
− | char lowvelocity; |
||
− | char highvelocity; |
||
− | short gain; |
||
− | Loop sustainLoop; |
||
− | Loop releaseLoop; |
||
− | } InstrumentChunk; |
||
− | |||
− | The ckID is always 'INST'. ckSize is the size of the data portion of the |
||
− | chunk, in bytes. For the Instrument Chunk, ckSize is always 20. |
||
− | |||
− | The baseNote is the note at which the instrument plays back the sound data |
||
− | without pitch modification. Units are MIDI (MIDI is an acronym for Musical |
||
− | Instrument Digital Interface) note numbers, and are in the range 0 through |
||
− | 127. Middle C is 60. |
||
− | |||
− | 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. |
||
− | |||
− | The lowNote and highNote fields specify the suggested range 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 low and high, inclusive. The base |
||
− | note does not have to be within this range. Units for lowNote and highNote |
||
− | are MIDI note values. |
||
− | |||
− | The lowVelocity and highVelocity fields specify the suggested range of |
||
− | velocities for playback of the sound data. The sound 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). |
||
− | |||
− | The gain is the amount by which to change the gain of the sound when it is |
||
− | played. Units are decibels. For example, 0db means no change, 6db means |
||
− | double the value of each sample point, while -6db means halve the value of |
||
− | each sample point. |
||
− | |||
− | The sustainLoop field specifies a loop that is to be played when an instrument |
||
− | is sustaining a sound. |
||
− | |||
− | The releaseLoop field specifies 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 Instrument Chunk is optional. No more than one Instrument Chunk can |
||
− | appear in a FORM AIFF. |
||
− | |||
− | ASIF Note: The Apple IIGS Sampled Instrument Format also defines a |
||
− | chunk with ID of "INST," which is not the same as the Audio |
||
− | IFF Instrument Chunk. A good way to tell the two chunks |
||
− | apart in generic IFF-style readers is by the ckSize fields. |
||
− | The Audio IFF 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. |
||
− | |||
− | |||
− | 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 Audio IFF 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. |
||
− | |||
− | #define MIDIDataID 'MIDI' /* ckID for MIDI Data Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | unsigned char MIDIdata[]; |
||
− | } MIDIDataChunk; |
||
− | |||
− | The ckID is always 'MIDI'. ckSize of the data portion of the chunk, in bytes. |
||
− | It does not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The MIDIData field contains a stream of MIDI data. |
||
− | |||
− | The MIDI Data Chunk is optional. Any number of MIDI Data Chunks may exist in |
||
− | a FORM AIFF. If MIDI System Exclusive messages for several instruments are to |
||
− | be stored in a FORM AIFF, 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. |
||
− | |||
− | #define AudioRecordingID 'AESD' /* ckID for Audio Recording */ |
||
− | /* Chunk. */ |
||
− | typedef struct { |
||
− | ID ckID |
||
− | long ckSize; |
||
− | |||
− | unsigned char AESChannelStatusData[24]; |
||
− | } AudioRecordingChunk; |
||
− | |||
− | The ckID is always 'AESD'. The ckSize is the size of the data portion of the |
||
− | chunk, in bytes For the Audio Recording Chunk, ckSize is always 24. |
||
− | |||
− | The 24 bytes of AESCChannelStatusData are specified in the "AES Recommended |
||
− | Practice for Digital Audio Engineering - Serial Transmission Format for Linearly |
||
− | Represented Digital Audio Data", transmission of digital audio between audio |
||
− | devices. This information is duplicated in the Audio Recording Chunk for |
||
− | convenience. Of general interest would be bits 2, 3, and 4 of byte 0, which |
||
− | describe recording emphasis. |
||
− | |||
− | The Audio Recording Chunk is optional. No more than one Audio Recording Chunk |
||
− | may appear in a FORM AIFF. |
||
− | |||
− | |||
− | 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. |
||
− | |||
− | #define ApplicationSpecificID 'APPL' /* ckID for Application */ |
||
− | /* Specific Chunk. */ |
||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | OSType applicationSignature; |
||
− | char data[]; |
||
− | } ApplicationSpecificChunk; |
||
− | |||
− | The ckID is always 'APPL'. The ckSize is the size of the data portion of the |
||
− | chunk, in bytes. It does not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The applicationSignature identifies a particular application. For Macintosh |
||
− | applications, this will be the application's four character signature. |
||
− | |||
− | The OSType field is used by applications which run on platforms from Apple |
||
− | Computer, Inc. For the Apple II, the OStype field should be set to 'pdos'. |
||
− | For the Macintosh, this field should be set to the four character signature |
||
− | as registered with Apple Technical Support. |
||
− | |||
− | The data field is the data specific to the application. |
||
− | |||
− | The Application Specific Chunk is optional. Any number of Application |
||
− | Specific Chunks may exist in a single FORM AIFF. |
||
− | |||
− | |||
− | The Comments Chunk |
||
− | |||
− | The Comments Chunk is used to store comments in the FORM AIFF. "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. |
||
− | |||
− | Comment |
||
− | |||
− | A comment consists of a time stamp, marker id, and a text count followed by |
||
− | text. |
||
− | |||
− | typedef struct { |
||
− | unsigned long timeStamp; |
||
− | MarkerID marker; |
||
− | unsigned short count; |
||
− | char text; |
||
− | } Comment; |
||
− | |||
− | The timeStamp indicates when the comment was created. On the Amiga, units |
||
− | are the number of seconds since January 1, 1978. On the Macintosh, units are |
||
− | the number of seconds since January 1, 1904. |
||
− | |||
− | A comment can be linked to a marker. This allows applications to store long |
||
− | descriptions of markers as a comment. If the comment is referring to a marker, |
||
− | then the marker field is the ID of that marker. Otherwise, marker is zero, |
||
− | indicating that this comment is not linked to a marker. |
||
− | |||
− | The count is the length of the text that makes up the comment. This is a 16-bit |
||
− | quantity, allowing much longer comments than would be available with a pstring. |
||
− | |||
− | The text field contains the comment itself. |
||
− | |||
− | The Comments Chunk is optional. No more than one Comments Chunk may appear in |
||
− | a single FORM AIFF. |
||
− | |||
− | |||
− | Comments Chunk Format |
||
− | |||
− | #define CommentID 'COMT' /* ckID for Comments Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | |||
− | unsigned short numComments; |
||
− | Comment comments[]; |
||
− | }CommentsChunk; |
||
− | |||
− | The ckID is always 'COMT'. The ckSize is the size of the data portion of |
||
− | the chunk, in bytes. It does not include the 8 bytes used by ckID and ckSize. |
||
− | |||
− | The numComments field contains the number of comments in the Comments Chunk. |
||
− | This is followed by the comments themselves. Comments are always even |
||
− | numbers of bytes in length, so there is no padding between comments in |
||
− | the Comments Chunk. |
||
− | |||
− | The Comments Chunk is optional. No more than one Comments Chunk may appear |
||
− | in a single FORM AIFF. |
||
− | |||
− | |||
− | The Text Chunks, Name, Author, Copyright, Annotation |
||
− | |||
− | 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. |
||
− | |||
− | #define NameID 'NAME' /* ckID for Name Chunk */ |
||
− | #define NameID 'AUTH' /* ckID for Author Chunk */ |
||
− | #define NameID '(c) ' /* ckID for Copyright Chunk */ |
||
− | #define NameID 'ANNO' /* ckID for Annotation Chunk */ |
||
− | |||
− | typedef struct { |
||
− | ID ckID; |
||
− | long ckSize; |
||
− | char text[]; |
||
− | }TextChunk; |
||
− | |||
− | |||
− | The ckID is either 'NAME', 'AUTH', '(c) ', or 'ANNO' depending on whether the |
||
− | chunk is a Name Chunk, Author Chunk, Copyright Chunk, or Annotation Chunk, |
||
− | respectively. For the Copyright Chunk, the 'c' is lowercase and there is a |
||
− | space (0x20) after the close parenthesis. |
||
− | |||
− | The ckSize is the size of the data portion of the chunk, in this case the text. |
||
− | |||
− | The text field contains pure ASCII characters. it is not a pstring or a C |
||
− | string. The number of characters in text is determined by ckSize. The |
||
− | contents of text depend on the chunk, as described below: |
||
− | |||
− | Name Chunk. The text contains the name of the sampled sound. The Name Chunk |
||
− | is optional. No more than one Name Chunk may exist within a FORM AIFF. |
||
− | |||
− | Author Chunk. The text contains one or more author names. An author in this |
||
− | case is the creator of a sampled sound. The Author Chunk is optional. No |
||
− | more than one Author Chunk may exist within a FORM AIFF. |
||
− | |||
− | Copyright Chunk. The Copyright Chunk contains a copyright notice for the |
||
− | sound. The text field contains a date followed by the name of the copyright |
||
− | owner. The chunk ID '(c) ' serves as the copyright character. For example, |
||
− | a Copyright Chunk containing the text "2012 Hyperion Entertainment" means |
||
− | "(c) 2012 Hyperion Entertainment" The Copyright Chunk is optional. No more |
||
− | than one Copyright Chunk may exist within a FORM AIFF. |
||
− | |||
− | Annotation Chunk. The text contains a comment. Use of this chunk is |
||
− | discouraged within a FORM AIFF. The more powerful Comments Chunk should be |
||
− | used instead. The Annotation Chunk is optional. Many Annotation Chunks may |
||
− | exist within a FORM AIFF. |
||
− | |||
− | Chunk Precedence |
||
− | |||
− | Several of the local chunks for FORM AIFF 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 illustrated in Figure 10. |
||
− | |||
− | Common Chunk Highest Precedence |
||
− | | |
||
− | Sound Data Chunk |
||
− | | |
||
− | Marker Chunk |
||
− | | |
||
− | Instrument Chunk |
||
− | | |
||
− | Comment Chunk |
||
− | | |
||
− | Name Chunk |
||
− | | |
||
− | Author Chunk |
||
− | | |
||
− | Copyright Chunk |
||
− | | |
||
− | Annotation Chunk |
||
− | | |
||
− | Audio Recording Chunk |
||
− | | |
||
− | MIDI Data Chunk |
||
− | | |
||
− | Application Specific Chunk Lowest Precedence |
||
− | |||
− | Figure 10: Chunk Precedence |
||
− | |||
− | The Common 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. |
||
− | |||
− | Figure 11 illustrates an example of a FORM AIFF. An Audio IFF file is simple |
||
− | a file containing a single FORM AIFF. The FORM AIFF is stored in the data |
||
− | fork of Macintosh file systems that can handle resource forks. |
||
− | |||
− | _____________________________________________________________________ |
||
− | | FORM AIFF | |
||
− | | _____________ | |
||
− | | ckID |_ 'FORM' ____| | |
||
− | | ckSize |_ 176516 ____| | |
||
− | | _____________ formType |_ 'AIFF' ____| __________________________ | |
||
− | | | Common ckID |_ 'COMM' ____| | | |
||
− | | | Chunk ckSize |_ 18 ________| | | |
||
− | | | numChannels |_ 2 ___|_____ | | |
||
− | | | numSampleFrames |_ 88200 _____| | | |
||
− | | | sampleSize |_ 16 __|_______________________________ | | |
||
− | | |___________ sampleRate |_ 44100.00 ____________________________| | | |
||
− | | | Marker ckID |_ 'MARK' _____| | | |
||
− | | | Chunk ckSize |_ 34 _________| | | |
||
− | | | numMarkers |_ 2 ___| | | |
||
− | | | id |_ 1 ___|_______ | | |
||
− | | | position |_ 44100 ___ ___|___ ___ ___ ___ ___ ___ | | |
||
− | | | markerName | 8 |'b'|'e'|'g'|' '|'l'|'o'|'o'|'p'| 0 | | | |
||
− | | | id |_ 2 ___|_______ | | |
||
− | | | position |_ 88200 _______|___ ___ ___ ___ ___ ___ | | |
||
− | | |___________ markerName | 8 |'e'|'n'|'d'|' '|'l'|'o'|'o'|'p'| 0 | | | |
||
− | | | Instrument ckID |_ 'INST' ______| | | |
||
− | | | Chunk ckSize |_ 20 __________| | | |
||
− | | | baseNote | 60| | | |
||
− | | | detune | -3| | | |
||
− | | | lowNote | 57| | | |
||
− | | | highNote | 63| | | |
||
− | | | lowVelocity | 1 | | | |
||
− | | | highVelocity |127|__ | | |
||
− | | | gain |_ 6 __| | | |
||
− | | | sustainLoop.playMode |_ 1 __| | | |
||
− | | | sustainLoop.beginLoop |_ 1 __| | | |
||
− | | | sustainLoop.endLoop |_ 2 __| | | |
||
− | | | releaseLoop.playMode |_ 0 __| | | |
||
− | | | releaseLoop.beginLoop |_ - __| | | |
||
− | | |__ releaseLoop.endLoop |_ - __|__________________________________| | |
||
− | | | Sound ckID |_ 'SSND' ______| | | |
||
− | | | Data ckSize |_ 176408 ______| | | |
||
− | | | Chunk offset |_ 0 ___________| | | |
||
− | | | blockSize |_ 0 ___________| _______ _______ | | |
||
− | | | soundData |_ch 1 _|_ch 2 _| . . . |_ch 1 _|_ch 2 _| | | |
||
− | | | first sample frame 88200th sample frame | | |
||
− | | |_________________________________________________________________| | |
||
− | |_____________________________________________________________________| |
||
− | |||
− | Figure 11: Sample FORM AIFF |
||
− | |||
− | |||
− | |||
− | Further Reference |
||
− | _____________________________________________________________________________ |
||
− | o "Inside Macintosh", Volume II, Apple Computer, Inc. |
||
− | o "Apple Numerics Manual", Second Edition, Apple Computer, Inc. |
||
− | o "File Type Note: File Type $D8, Auxiliary Type $0002, Apple IIGS |
||
− | Sampled Instrument Format", Apple Computer, Inc. |
||
− | o "Audio Interchange File Format v1.3", APDA |
||
− | o "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 |
||
− | o "MIDI: Musical Instrument Digital Interface, Specification 1.0", the |
||
− | International MIDI Association. |
||
− | o "`EA IFF 85' Standard for Interchange Format Files", Electronic Arts |
||
− | o "`8SVX' IFF 8-bit Sampled Voice", Electronic Arts |
||
− | </pre> |