Sound Resources
Sound Resources The role of the 'snd' resources
The Sound Manager uses two types of resources to help it interpret and
play sounds: 'snd ' resources (also called sound resources) and 'snth'
resources (also called sound synthesizers). The 'snth' resources are code
resources that interpret Sound Manager commands and data destined for a
particular synthesizer. Apple provides 'snth' resources for all three supported
synthesizers, which are contained in the System file. Applications generally do
not need to know anything about 'snth' resources.
Resources of type 'snd ' can contain both sound commands and sound data, and
are widely used by sound-producing applications. These resources provide a
simple and portable way for you to incorporate sounds into your applications.
For example, the sounds that a user can select in the Sound control panel as
the system alert sound are stored in the System file as 'snd' resources. Unless
you use the new sound-recording routines of the enhanced
Sound Manager, creating 'snd ' resources requires an understanding of
sound synthesis to build a sampled sound header, wave-table data, or sound
commands. You can also use the SetupSndHeader function to help you create
an 'snd ' resource (format 1).
There are two types of 'snd ' resources, known as format 1 and format 2. The
Figure below illustrates the structures of both kinds of 'snd ' resources.
Note: Resource IDs for 'snd ' resources in the range 0 to 8191 are
reserved for use by Apple. The 'snd ' resources numbered 1 through 4
are defined to be the standard system alert sounds.
The format 1 'snd ' resource is the most general kind of sound resource. A
format 1 'snd ' resource may contain a specification of the intended output
synthesizer, along with a sequence of Sound Manager commands and
associated sound data (such as a sampled sound header or a wave table). In this
case, your application can produce sounds simply by passing a handle to that
resource to the SndPlay function, which loads the specified synthesizer into
memory, opens a sound channel, and sends the commands and data contained in
the resource into the channel. Alternatively, a format 1 'snd ' may contain a
sequence of commands that describe a sound, without specifying a synthesizer
and without providing any other sound data. In this case, your application can
use the SndPlay function to play the sound on any channel. Accordingly, you
can use a format 1 'snd ' with any one of the available synthesizers.
The structure of 'snd ' resources
The format 2 'snd ' resource is obsolete and your applications should use
format 1 'snd ' resources. The format 2 'snd ' resource was designed for use by
HyperCard and can be used with the sampled sound synthesizer only. A format 2
'snd ' resource simply contains a sound command that points to a sampled
sound header.
When a sound command contained in an 'snd ' resource has associated sound
data, the high bit of the command is set. This changes the param2 field of the
command to an offset value that specifies the distance in bytes from the
resource's beginning to the location of the associated sound data. The Figure
below illustrates the location of this data offset bit.
The location of the data offset bit
The offset bit is used only by sound commands that are stored in sound
resources of type 'snd ' and that have associated sound data (that is,
sampled sound or wave-table data). If the high bit of the command is set, then
param2 is interpreted as an offset in bytes from the beginning of the sound
resource to the associated data.
You can use a constant to set that flag.
dataOffsetFlag sound command data offset bit
If the offset bit is not set, param2 is interpreted instead as a pointer to the
location in memory (outside the sound resource) where the data is located.
To calculate the offset for a format 1 'snd ' resource, use the following
formula:
offset = 6 + (number of synthesizers * size of synthesizer information) +
(number of commands * size of command)
For example, if a format 1 'snd ' resource specifies that a sound channel is to
be linked to a synthesizer and if that resource contains a single sound command
(perhaps bufferCmd), then the offset from the beginning of the resource to the
associated sound data is as follows:
offset = 6 + (1 * 6) + (1 * 8) = 20 bytes
To calculate this offset for a format 2 'snd ' resource, use this formula:
offset = 6 + (number of commands * 8)
The first few bytes of the resource contain 'snd ' header information and are a
different size for each format. A synthesizer specified in a format 1 'snd '
requires 6 bytes. The number of synthesizers multiplied by 6 is added to this
offset. The number of commands multiplied by 8 bytes, the size of a sound
command, is added to the offset.
The Format 1 'snd ' Resource
The Figure above shows the fields of a format 1 'snd ' resource. A format 1
'snd ' resource contains information about the format of the resource (namely,
1), the intended output synthesizer, and the initialization options for that
synthesizer. A format 1 'snd ' resource may also contain the actual sound data
for the wave-table synthesizer or the actual sound data for the
sampled sound synthesizer.
If an 'snd ' resource specifies a synthesizer, it can supply an initialization
option in the field immediately following the resource ID. You specify the
number of commands in the resource in the number of sound commands field.
The sound commands follow in the order in which they should be sent to the
channel.
The format 1 'snd ' resource might contain only a sequence of commands
describing a sound that can be played by any synthesizer. In this case, the
number of synthesizers should be 0, and there should be no synthesizer
resource ID or initialization option in the 'snd ' resource. This allows the 'snd '
to be used on any channel.
The following Listing shows the output of the MPW tool DeRez when applied to
the 'snd ' resource with resource ID 1 contained in the System file.
A format 1 'snd ' resource
data 'snd ' (1, "Simple Beep", purgeable) {
0x"00 01 00 01 00 01 00 00 00 00 00 1B 00 2C 00 5A
0x"00 00 00 00 00 2B 00 E0 00 00 00 00 00 2A 00 00
0x"00 00 00 45 00 0A 00 28 00 00 00 00 00 2B 00 C8
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 C0
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 B8
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 B0
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 A8
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 A0
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 90
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 80
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 60
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 40
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 20
0x"00 00 00 00 00 0A 00 28 00 00 00 00 00 2B 00 00
0x"00 00 00 00
};
In the Listing above DeRez simply lists the raw data contained in that
resource. To make sense of this data, see the Listing below, which shows the
same data re structured and commented.
Listing: A re structured format 1 'snd ' resource
data 'snd ' (1, "Simple Beep", purgeable) {
0x"0001" //format type
0x"0001" //number of synthesizers
0x"0001" //resource ID of square-wave synthesizer
0x"00000000" //initialization option
0x"001B" //number of sound commands that follow (27)
0x"002C" //command 1-- timbreCmd 090 000
0x"005A00000000
0x"002B" //command 2--ampCmd 224 000
0x"00E000000000
0x"002A" //command 3--freqCmd 000 069
0x"000000000045
0x"000A" //command 4--waitCmd 040 000
0x"002800000000
0x"002B" //command 5--ampCmd 200 000
0x"00C800000000
// commands 6 through 26 are omitted; they are alternating pairs
// of waitCmd and ampCmd commands, where the first parameter of
// ampCmd has the values
// 192, 184, 176, 168, 160, 144, 128, 96, 64, and 32
0x"002B" //command 27--ampCmd 000 000
0x"000000000000
};
As you can see, the Simple Beep is actually a rather sophisticated sound,
where the loudness (or amplitude) of the beep gradually decreases from an
initial value of 224 to 0.
Notice that the sound described in the previous two listings is played by the
square-wave synthesizer and is completely determined by a sequence of
specific commands. ("Play an A at loudness 224, wait 20 milliseconds, play it
at loudness 200....") Often an 'snd ' resource consists only of a single
sound command (usually the bufferCmd command) together with data that
describes a sampled sound to be played. The next Listing below illustrates an
example like this; once again, the output of DeRez has been re structured and
commented to improve read ability.
Listing: A format 1 'snd ' resource containing sampled sound data
data 'snd ' (19068, "hello daddy", purgeable) {
0x"0001" //format type
0x"0001" //number of synthesizers
0x"0005" //resource ID of first synthesizer
0x"00000080" //initialization option: initMono
0x"0001" //number of sound commands that follow (1)
0x"8051" //command 1-- bufferCmd
0x"0000" // param1 = 0
0x"00000014" // param2 = offset to sound header (20 bytes)
0x"00000000" //pointer to data (it follows immediately)
0x"00000BB8" //number of bytes in sample (3000 bytes)
0x"56EE8BA3" //sampling rate of this sound (22 kHz)
0x"000007D0" //starting of the sample's loop point
0x"00000898" //ending of the sample's loop point
0x"00" //standard sample encoding
0x"3C" //baseFrequency at which sample was taken
//the sampled sound data
0x"80 80 81 81 81 81 81 81 80 80 80 80 80 81 82 82
0x"82 83 82 82 81 80 80 7F 7F 7F 7E 7D 7D 7D 7C 7C
0x"7C 7C 7D 7D 7D 7D 7E 7F 80 80 81 81 82 82 83 83
0x"83 83 82 81 81 80 80 81 81 81 81 81 82 81 81 80
0x"80 80 81 81 81 83 83 83 82 81 81 80 7F 7E 7D 7D
0x"7F 7F 7F 7F 7E 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 80
//rest of data omitted in this example
};
This 'snd ' resource specifies the sampled sound synthesizer and includes a
call to a single sound command, the bufferCmd command. The offset bit of the
command number is set to indicate that the sound data is contained in the
resource itself. Following that command and its two parameters is the sampled
sound header, the first part of which contains important information about the
sample. The second parameter to the bufferCmd command indicates the offset
from the beginning of the resource to the sampled sound header, in this case
20 bytes.
It is not always necessary to specify 'snd ' resources by listing the raw data
stream contained in them; indeed, for certain types of format 1 'snd '
resources, it can be easier to supply a resource specification like the one given
in the Listing below.
Listing: A resource specification
resource 'snd ' (9000, "New Beep", purgeable) {
FormatOne {
{ //array Synthesizers: 1 element
//[1]
squareWaveSynth, 0
}
},
{ //array SoundCmnds: 3 elements
//[1]
noData, timbreCmd {90},
//[2]
noData, freqDurationCmd {480, 0x00000045},
//[3]
noData, quietCmd {},
},
{ //array DataTables: 0 elements
};
};
When you pass a handle to this resource to the SndPlay function, three
commands are executed by the square-wave synthesizer: a timbreCmd
command, a freqDurationCmd command, and a quietCmd command. The sound
specified in the Listing immediately above is just like the Simple Beep, except
that there is no gradual reduction in the loudness. To duplicate the Simple Beep
exactly, you could use the resource specification given in the Listing below.
Listing: Resource specification for the Simple Beep
resource 'snd ' (9001, "Copy of Simple Beep", purgeable) {
FormatOne {
{ //array Synthesizers: 1 element
//[1]
squareWaveSynth, 0
}
},
{ //array SoundCmnds: 27 elements
//[1]
noData, timbreCmd {90},
//[2]
noData, ampCmd {224},
//[3]
noData, freqCmd {69},
//[4]
noData, waitCmd {40},
//[5]
noData, ampCmd {200},
//[6]
noData, waitCmd {40},
//[7]
noData, ampCmd {192},
//[8]
noData, waitCmd {40},
//[9]
noData, ampCmd {184},
//[10]
noData, waitCmd {40},
//[11]
noData, ampCmd {176},
//[12]
noData, waitCmd {40},
//[13]
noData, ampCmd {168},
//[14]
noData, waitCmd {40},
//[15]
noData, ampCmd {160},
//[16]
noData, waitCmd {40},
//[17]
noData, ampCmd {144},
//[18]
noData, waitCmd {40},
//[19]
noData, ampCmd {128},
//[20]
noData, waitCmd {40},
//[21]
noData, ampCmd {96},
//[22]
noData, waitCmd {40},
//[23]
noData, ampCmd {64},
//[24]
noData, waitCmd {40},
//[25]
noData, ampCmd {32},
//[26]
noData, waitCmd {40},
//[27]
noData, ampCmd {0}
},
{ //array DataTables: 0 elements
}
};
The Format 2 'snd ' Resource
The SndPlay function can also play format 2 'snd ' resources, which are
designed for use only with the sampled sound synthesizer. The SndPlay
function supports this format by automatically opening a channel to the
sampled sound synthesizer and using the bufferCmd command to send the data
contained in the resource to that synthesizer.
The first Figure in the section above illustrates the fields of a format 2 'snd '
resource. The reference count field is for your application's use and is not used
by the Sound Manager. The number of sound commands field and the sound
command fields are the same as described in a format 1 resource. The last field
of this resource contains the sampled sound. The first command should be
either a soundCmd command or bufferCmd command with the data offset bit set
in the command to specify the location of this sampled sound header.
The Listing below shows a resource specification that illustrates the
structure of a format 2 'snd ' resource; it contains the information necessary
to create a sound with SndPlay and the sampled sound synthesizer.
Listing: A format 2 'snd ' resource
data 'snd ' (9003, "Pig Squeal", purgeable) {
0x"0002" //format type
0x"0000" //reference count for application's use
0x"0001" //number of sound commands that follow (1)
0x"8051" //command 1-- bufferCmd
0x"0000" // param1 = 0
0x"0000000E" // param2 = offset to sound header (14 bytes)
0x"00000000" //pointer to data (it follows immediately)
0x"00000BB8" //number of bytes in sample (3000 bytes)
0x"56EE8BA3" //sampling rate of this sound (22 kHz)
0x"000007D0" //starting of the sample's loop point
0x"00000898" //ending of the sample's loop point
0x"00" //standard sample encoding
0x"3C" //baseFrequency at which sample was taken
0x"80 80 81 82 84 87 93 84" //the sampled sound data
0x"6F 68 6D 65 72 7B 82 88
0x"91 8E 8D 8F 86 7E 7C 79
0x"6F 6D 71 70 70 79 7F 81
0x"89 8F 8D 8B" //rest of data omitted in this example
};
For a complete explanation of the fields following the sampling rate field, see
Playing Sampled Sounds. To play the sounds described by these resources,
see the in structions given in Playing 'snd ' Resources.