SDII format specification
3 December 2004
Sound Designer I file format is the original Digidesign sound file format first released in 1985. It is widely used and supported as evidenced
by the many CD ROM discs with sound effects stored in this format. It is primarily used to store mono 16 bit short duration (on the order
of seconds) audio samples. We recommend that you support this format for short sounds, but that you use Sound Designer II format as a primary format due to its flexibility.
File Type: 'SFIL’
Resource Fork
================
The resource fork is not used.
Data Fork
===========
The first 1336 bytes of the data fork contain the sound header (see the Pascal HeaderType record below) followed by the sample data itself. The most important
fields are in bold. Default values are given in ( ) within the comment next to a field. Byte offsets are indicated to the left at various offsets. Fields with the comment DO NOT USE are for Sound Designer internal use and should not be changed except when initializing the file. The size of the data types are detailed in Inside Macintosh, Volume 1, page 86.
typedef struct<br /> MarkerType<br /> {<br /> Boolean Free;<br /> // TRUE if this marker is free for use (TRUE/1).
long<br /> Position;<br /> // Byte position in file (0).<br /> char<br /> Name33;<br /> // Name of the marker (“Untitled”).<br /> } MarkerType;
enum SideType {kLeftSide,kRightSide};
typedef struct EditRecord<br /> {<br /> long HiAddr;<br /> // DO NOT USE (0).
long LoAddr;<br /> // DO NOT USE (0).<br /> enum<br /> SideType<br /> ExtendSide; // DO NOT<br /> USE (0).<br /> } EditRecord;
enum ScaleNames {kTime,kSampleNumber,kHexSampNum,kVolts,<span<br /> ></span>kPercent,kdbm,kUser};<br /> enum ModeType {kSelect,kDraw,kZoomSelect};
typedef struct ZoomType<br /> {<br /> short<br /> v; // Vertical<br /> scale factor: positive = magnification
<br /> <br /> // negative =<br /> reduction (-256).<br /> long<br /> h; // Horizontal<br /> scale factor: positive = magnification
<br /> <br /> // negative =<br /> reduction (1)}<br /> } ZoomType;
typedef struct ScaleType<br /> {<br /> long<br /> VFactor;<br /> // Scale factor for vertical axis tick<br /> units:<br /> <br /> <br /> <br /> // positive =<br /> magnification,
<br /> <br /> // negative =<br /> reduction (327).<br /> enum ScaleNames<br /> VType; // Type of vertical axis tick<br /> mark unit (4).<br /> char<br /> VString34; // Vertical<br /> axis tick units string (”%Scale”).<br /> long<br /> HFactor;<br /> // Scale factor for horizontal axis tick units:<br /> <br /> <br /> // positive =<br /> magnification
<br /> <br /> // negative =<br /> reduction (1).<br /> enum<br /> ScaleNames HType; // Type of<br /> horizontal axis tick mark unit (0).<br /> <br /> char<br /> HString34; // Horizontal<br /> axis tick units string:
<br /> <br /> //<br /> sec,msec,sec,samples (“sec”).<br /> } ScaleType;
typedef struct <b>HeaderType<br /> </b>{<br /> <b> short<br /> HeaderSize; // Size in<br /> bytes of the file header (1336).<br /> </b> short<br /> Version;<br /> // DO NOT USE (32).<br /> Boolean<br /> Preview;<br /> // DO NOT USE (0).
WindowPtr<br /> WPtr; // DO NOT USE (0).
WindowPeek<br /> WPeek; // DO NOT USE (0).
long<br /> HInxPage,HInxLine;<br /> // DO NOT USE (0).
long<br /> VInxPage,VInxLine;<br /> // DO NOT USE (0).
long<br /> HCtlPage,HCtlLine;<br /> // DO NOT USE (0).
long<br /> VCtlPage,VCtlLine;<br /> // DO NOT USE (0).
long<br /> VOffset;<br /> // Position of vertical center of window in quantization
<br /> <br /> // units ie<br /> -32768 to 32767 (0).<br /> long<br /> HOffset;<br /> // Position of left edge of sample window in #SAMPLES (0).
short<br /> VOffConst; // DO<br /> NOT USE (0).
ZoomType<br /> Zoom; // See above.
ScaleType<br /> Scale; // See above.<br /> short<br /> VScrUpdate; // DO NOT<br /> USE (0).
Ptr BufPtr;<br /> // DO NOT USE (0).
Size<br /> BufBytes;<br /> // DO NOT USE (0).
long<br /> BufOffset; // DO<br /> NOT USE (0).
RgnHandle<br /> WaveRgn;<br /> // DO NOT USE (0).
RgnHandle<br /> ClipArea;<br /> // DO NOT USE (0).
RgnHandle<br /> ScaleArea; // DO<br /> NOT USE (0).
Rect<br /> CtlWidth;<br /> // DO NOT USE (0).
ControlHandle<br /> VScroll;<br /> // DO NOT USE (0).
ControlHandle<br /> HScroll;<br /> // DO NOT USE (0).<br /> <b><br /> Size<br /> FileSize;<br /> // 2 * number of samples in this file ie number<br /> <br /> <br /> // of bytes of<br /> sound data.<br /> </b> char<br /> BUName66; // Name of<br /> edit backup file.<br /> <b> char<br /> FileName66; // Name of this file<br /> (Mac Filename).</b></div><br /> <div><font face=“Courier”<br /> ><br /> short<br /> BURefNum;<br /> // DO NOT USE (0).
short<br /> refNum;<x-tab<br /> > </x-tab>// DO NOT USE (0).
short<br /> vRefNum;<br /> // DO NOT USE (0).<br /> Boolean<br /> BufChanged; // DO NOT<br /> USE (0).<br /> Boolean<br /> FileChanged; // DO NOT USE<br /> (0).<br /> Boolean<br /> NoBackup;<br /> // DO NOT USE (0).<br /> enum<br /> ModeType Mode;<br /> // DO NOT USE (0).
EditRecord<br /> Edit; // See above.<br /> long<br /> CursorPos; //<br /> Cursor position relative to window start (0).
RgnHandle<br /> CursorRgn; //<br /> Cursor region in which it can be grasped (0).
MarkerType<br /> MarkerData10; // See above.<br /> long<br /> MarkerOffset; // Offset to get<br /> relative time (0).<br /> long<br /> LoopStart; //<br /> Starting byte # of loop (-1).
long<br /> LoopEnd;<br /> // Ending byte # of loop (-1).<br /> Boolean<br /> ZeroLineOn; //<br /> (FALSE/0).<br /> Boolean<br /> CursorOn;<br /> // (FALSE/0).<br /> Boolean<br /> ScalesOn;<br /> // (FALSE/0).<br /> Str255<br /> Comment;<br /> // File comment (” “).<br /> long<br /> SampRate;<br /> // Sample rate in hertz ie 44100.
long<br /> SampPeriod; // Sample period in microseconds.
short<br /> SampSize;<br /> // Number of bits in a sample (16).
char<br /> CodeType34; // Type of sample data (“Linear”).<br /> Str255<br /> UserStr1;<br /> // For user comments or reserved for future.<br /> Size<br /> BufSize;<br /> // Size of the RAM wave buffer in bytes.
long<br /> Loop2Start; // Release loop start in bytes (-1).<br /> long<br /> Loop2End;<br /> // Release loop end in bytes (-1).
Byte<br /> Loop1Type; // Type of loop: 1 = forward 2 = forward/backward.
Byte<br /> Loop2Type; // Type of loop: 1 = forward 2 = forward/backward.
short User4;<br /> // DO NOT USE (0).<br /> } <b>HeaderType</b>;
Sound Designer I File Header Notes
====================================
Shorts (2 bytes) and longs (4 bytes) are stored in Motorola 68000 format with the most significant bytes stored first, followed by the least significant bytes. For example, to store the hexadecimal value 0123 4567 as a long, we would store in ASCENDING memory locations: 01, 23, 45, 67. Leading zeros must be considered as part of the number.
The total length of the header is 1336 bytes. It is the first thing in the file, so if a file is rewound to an offset of 0 from the beginning of the file, the file position marker will be pointing to the first byte in the header.
If a default value is given for a variable in the header, it MUST be set to that value when creating the header for the first time. All default values for numeric data in the header are given in DECIMAL. A header variable with the comment “DO NOT USE” should be set to its default value when creating a file, and under no circumstances used otherwise.
The notation for strings in the Macintosh is STR[NN] where NN is the length in bytes of the string. The actual string stored in memory or the header will have one extra byte preceding it. This byte contains the length of the string, NN. For example to store a STR32 in the header, the first byte will be 32 (decimal), followed by 32 bytes of ASCII representing the string. A string constant is specified above by using quote marks ie (” “). DO NOT include the quote marks as part of the string itself. Note that the string values in the header give the MAXIMUM length of that string variable. If you wish to use a string which is shorter (and you usually will), then the first byte of that string should give the actual number of ASCII characters in the string you wish to use. For example, although FileName is specified as a char66, you may wish to use less characters for a filename. If you wish to use “New File” as the filename, you would store the byte 08 (ie the length not including the length byte itself) followed by the ASCII values for the characters in the string “New File”. The byte 08 says that there are 8 bytes in the string itself.
End addresses, such as Loop End addresses are the address of the first byte AFTER the last byte IN THE LOOP. They DO NOT refer to the last byte of the loop. Start addresses, however, refer to the first byte of a selection.
There are currently no user bytes available in the header for independent use. This does not preclude the possibility that there will be some date, however at this time you must assume that no bytes in the header may be used for any purpose other than described above. All bytes which are NOT listed above are reserved for use exclusively by Digidesign Inc. until further notice.
Sound Designer II File Format
=========================
Sound Designer II files store all sound samples in the data fork and all sound parameters in the resource fork. This is extremely convenient for sound data where the data fork may grow to a hundred megabytes or more. Regardless of the size of the data fork you can add, delete, and modify sound parameters at will without compacting the sound data or moving it around the disk (and extremely time consuming procedure if the file is 100 MB). In addition, you may add your own parameters to a file (as long as their resource types don’t conflict with Sound Designer II’s) while allowing the file to be read by both Sound Designer and your program. We recommend that developers standardize on the Sound Designer II file format as the primary format due to its ability to be customized. For multi-track operations, we recommend that each track be recorded in a separate single mono Sound Designer II file using stereo Sound Designer II files as the mastering medium.
File Type: 'Sd2f’
Resource Fork
The resource fork contains many different kinds of resources which specify everything from the sample rate to loop points to graphic eq settings. Most of these are application-specific to Sound Designer II. There are three core parameters/rsrcs in an SDII file:
Type: 'STR
' ID:
1000
Name: 'sample-size’
Integer numeric string specifying the number of bytes per sample (ie 2 for standard 16 bit samples).
Type: 'STR
' ID:
1001
Name: 'sample-rate’
Floating point numeric string specifying the sample rate in hertz of the file (ie ’44100.0000’ for a standard 44.1kHz sample rate file).
Type: 'STR
' ID:
1002
Name: 'channels’
Integer numeric string specifying the number of channels in the file (ie 2 for stereo).
The above resources are all that are specifically required in an SDII file. Given only these three parameters, Sound Designer II can read in and play the file. If your program modifies the sound data or above 'STR ' resources in any way, it is your responsibility to delete any other resources that may have become out of sync with the file. This can happen if you delete a large section of the file without updating the playlist pointers. Notice that the length of the file is not stored. This is because you can derive the length given the sample size, number of channels, and the length in bytes of the data fork (using file system calls) using the following formulas:
Length of file (in sample frames) = Length of data fork /(number of channels * sample size)
Length of file (in seconds) = (Length of data fork /(number of channels * sample size)) / sample rate
The following resources store file information used by Sound Designer II for various advanced playback and processing. Unlike the above core parameters, these are stored as Pascal RECORD structures written out to resources. Therefore they are defined by the associated Pascal RECORD definitions below. Default values are given in ( ) within the comment next to a field. Byte offsets are indicated to the left at various offsets. Fields with the comment DO NOT USE are for Sound Designer internal use and should not be changed except when initializing the file. The size of the data types are detailed in Inside Macintosh, Volume 1, page 86.
Type:
'sdDD’ ID: 1000
Stores general document information such as comments. A DocumentDataRecord as defined below.
typedef struct<br /> EditRecord<br /> {<br /> long HiAddr;<br /> // DO NOT USE (0).
long LoAddr;<br /> // DO NOT USE (0).<br /> enum SideType<br /> ExtendSide; // DO NOT USE (0).<br /> } EditRecord;
typedef struct ZoomType<br /> {<br /> short<br /> v; // Vertical scale factor: positive = magnification<br /> // negative =reduction (-256).
long<br /> h; // Horizontal scale factor: positive = magnification<br /> // negative = reduction (1).
} ZoomType;
typedef struct ScaleType<br /> {<br /> long<br /> VFactor;<br /> // Scale factor for vertical axis tick units:<br /> <br /> // positive = magnification
// negative = reduction (327)<br /> enum ScaleNames<br /> VType; // Type of vertical axis tick mark unit (4).<br />
char<br /> VString34; // Vertical axis tick units string (”%Scale”).<br /> long<br /> HFactor;<br /> // Scale factor for horizontal axis tick units:<br /> <br /> <br /> // positive = magnification
<br /> <br /> // negative = reduction (1).<br /> enum ScaleNames<br /> HType; // Type of horizontal axis tick mark unit (0).<br /> char<br /> HString34; // Horizontal axis tick units string:
// sec,msec,sec,samples (“sec”).<br /> } ScaleType;
typedef struct DocumentDataRecord<br /> {<br /> short<br /> Version;<br /> // version/format of this resource(1).<br /> long<br /> BufOffset; // DO NOT USE (0).
long<br /> MarkerOffset; // Offset to get relative time of markers.<br /> Str255<br /> Comment;<br /> // File comment (” “).<br /> short<br /> HDPlayBufMultiple;<br /> // HD play buf multiple for this file (8).
long SMPTEStartTime;<br /> // SMPTE start time of this file (0).<br /> short<br /> FramesPerSec; // SMPTE frame rate of this file (30).<br /> short<br /> FilmSize;<br /> // 16mm or 35mm film (35).
long<br /> StartBarNum; // Starting Bar Number (0).<br /> long<br /> StartBeatNum; // Starting Beat Number (0).<br /> long<br /> StartFrame; // The sample frame this new entry starts at<br /> Fixed<br /> Tempo; // Tempo in beats/sec.<br /> Fixed<br /> TimeSignature; // HiWord = numerator, LoWord = denominator.<br /> long<br /> CursorPos; // Cursor position relative to window start (0).
Boolean<br /> CursorOn;<br /> // (FALSE/0)
ZoomType<br /> Zoom; // See above.
ScaleType<br /> Scale; // See above.
EditRecord<br /> Edit; // See above.<br /> long<br /> VOffset;<br /> // Position of vertical center of window in quantization
<br /> <br /> // units ie -32768 to 32767 (0).<br /> long<br /> HOffset;<br /> // Position of left edge of sample window in #SAMPLES (0).
Rect<br /> CtlWidth;<br /> // DO NOT USE (0.
Point<br /> ZoomIndex; // h and v indices in zoom increments.<br /> short<br /> SelectMode; // DO NOT USE (0).<br /> } DocumentDataRecord;
Type:
'sdML’ ID: 1000
Stores a list of text and numeric markers.
short<br /> Version;<br /> // Version/format of this resource(1).<br /> long<br /> MarkerOffset; // DO NOT USE (0).
short<br /> NumMarkers; // Number of MarkerRecords to follow.
Followed by NumMarkers of the following record.
typedef struct<br /> MarkerRecord<br /> {
short<br /> MarkerType0; // 1 = numbered marker, 2 = text marker (1).<br /> short<br /> MarkerType1; // DUPLICATE of previous value – <i>for historical reasons.</i>
long<br /> Position;<br /> // Sample frame in file.
long<br /> Text; // DO NOT USE (0).
short<br /> CursorID;<br /> // 24430 = numeric, 3012 = text (24430).
short<br /> MarkerID;<br /> // Unique unsigned ID for each marker.<br /> long<br /> TextLength; // length of marker text.
char<br /> TheText[]; // The Text (ie TextLength bytes of ASCII characters).<br /> } MarkerRecord;
Type: 'sdLL’ ID: 1000
Stores a list of audio loops (commonly used with samplers).
short<br /> Version;<br /> // Version/format of this resource(1).<br /> short HScale;<br /> // DO NOT USE (1).
short VScale; // DO NOT USE (9).
short<br /> NumLoops;<br /> // number of LoopRecords to follow.
Followed by NumLoops of the following records:
typedef struct<br /> LoopRecord<br /> {<br /> long<br /> LoopStart; // Reference to start sample frame of this loop.
long<br /> LoopEnd;<br /> // Reference to end sample frame of this loop.<br /> short<br /> LoopIndex; // Identifies which loop this is (1..NumLoops).<br /> short<br /> LoopSense; // 117=forward loop, 118=backwards/forwards loop.
short<br /> Channel;<br /> // Channel which loop is on (0..NumChannels-1).<br /> } LoopRecord;
Region List Resource Spec
=====================
Type: 'ddRL’ ID: 1000
short VersionNumber;<br /> // Version of resource: 1 for current.<br /> long<br /> HeaderSize; // Size of the header in bytes NOT-INCLUDING VersionNumber
<br /> <br /> // and HeaderSize.<br /> long<br /> RegionSize; // Size of each region in bytes.
long<br /> ResourceDate; // Time stamp for last modification ie ticks since 1904….
// see IM vol ?<br /> long<br /> NextID; // The next kosher RegionID to be used for the next region created.
Followed by a variable number of RegionRec’s of the following format:
typedef struct<br /> RegionRec<br /> {<br /> long<br /> RegionID;<br /> // Unique within a file, not necessarily in order.
long<br /> StartFrame; // Number of sample frames into the file that the region
<br /> <br /> // starts.<br /> long<br /> StopFrame; // Ditto as above but the frame past the end ie + 1.<br /> long<br /> SynchFrame; // Absolute frame number (ie not relative to region start)
<br /> <br /> // for synch.
long<br /> TimeStampMS; // Most significant long of time stamp ie time of day
<br /> <br /> // absolute stamp.<br /> long<br /> TimeStampLS; // Least significant long of time stamp ie time of day
<br /> <br /> // absolute stamp. Time stamp viewed as one 64 bit
<br /> <br /> // number is the number of sample frames since the<br /> <br /> <br /> // Macintosh start time ie 1904.
Str31<br /> RegionName; // 31 character name NOT UNIQUE OR MEANINGFUL.<br /> } RegionRec;
The first RegionRec shall be a special one such that it represents the entire file. Its fields are as follows:
typedef struct<br /> RegionRec<br /> {
long<br /> RegionID;<br /> // 0.<br /> long<br /> StartFrame; // 0.<br /> long<br /> StopFrame; // Undefined and not to be used – so the length of a file
<br /> <br /> // is never stored…
long<br /> SynchFrame; // As specified above.<br /> long<br /> TimeStampMS; // Current time of day.<br /> long<br /> TimeStampLS; // Current time of day.<br /> Str31<br /> RegionName; // Same as the filename.<br /> } RegionRec;
Reserved Parameter/Resource Types
=============================
Digidesign reserves all resource types that begin with the letters 'sd’ or 'dd’ (capital and lower case) ie 'sdPL’, 'SDxx’, 'DDxx’ or 'dDxx’, for present and future use by Sound Designer II and other Digidesign programs.
Data Fork
=====
The data of a Sound Designer II file is stored in Two’s Complement encoding. Byte one of the data fork is the first byte of sound data. The sound data is organized as interleaved samples (if more then one channel) of either 8 or 16 bit samples depending on the value of the 'sample-size’ STR resource (see below).
For example, a standard 16 bit stereo file would be organized as follows:
Left Channel sample #1<br /> Right Channel sample #1<br /> Left Channel sample #2<br /> Right Channel sample #2<br /> Left Channel sample #3<br /> Right Channel sample #3<br /> etc...
Where each sample is the MSB (most significant byte) followed by the LSB (least significant byte) or better known as little endian format.
[ wrong ! its big endian ]
A four channel file would be as follows:
Channel 1 sample #1<br /> Channel 2 sample #1<br /> Channel 3 sample #1<br /> Channel 4 sample #1<br /> Channel 1 sample #2<br /> Channel 2 sample #2<br /> Channel 3 sample #2<br /> Channel 4 sample #2<br /> etc...