# Players, Sounds, and Markers

## Players

The top level data structure used by the advanced sound player is called an `SPPlayer`. Each `SPPlayer` contains a sound spooler, a sample player instrument, a set of buffers, and control information necessary to manage playback. A task can have multiple `SPPlayer`s, as long as they do not compete for the same media (e.g. two or more `SPPlayer`s trying to play sound from a CD at the same time is not likely to work).

## Sounds

`SPPlayer`s also contain a set of `SPSound`s they can play. An `SPSound` is a handle to sound data source. Currently two kinds of sound sources are supported: AIFF sound files and sample items. The difference is that AIFF sound files are spooled directly from disc and sample items are played entirely from memory. Since `SPSound`s built around sample items do not require access to the CD during playback, they can be used to keep playing sound while accessing the CD for something else. Other than that, different kinds of `SPSound`s are treated identically by the advanced sound player.

The set of `SPsound`s belonging to an `SPPlayer` can be managed at any time, even during playback. All of the `SPSound`s belonging to an `SPPlayer` must have the same sample format: number of channels, sample width, compression type and ratio.

## Markers

Each `SPSound` can have a set of markers at key sample positions within the sound data. These `SPMarker`s can be defined in the following ways:

- Markers and loop points from an AIFF file.
- Loop points from a sample item.
- Begin and end markers (intrinsic `SPMarker`s created by the advanced sound player for all `SPSound`s).
- `SPMarker`s created by the client.

Any of the `SPMarker`s can be set to cause playback to branch seamlessly (without any audible pops or clicks) to another `SPMarker` within the same `SPSound` or any of the other `SPSound`s that have been added to the `SPPlayer`.

By default, `SPMarker`s do nothing during playback. Also, by default, when the end of the sound data for the currently playing `SPSound` is reached, playback automatically stops. This can be changed by the client by correct placement of branches either before or during playback. The following examples illustrate a few things that can be done with markers.

## Examples of looping and branching

Here are some simple modifications to the previous annotated example to do some simple branching.

### Play Several Sound Files Sequentially

Substitute these steps in the annotated example to link several sounds together for seamless playback.

1. Specify which sound files you want to play.

     `spAddSoundFile (&first_sound, player, filename);
     spAddSoundFile (&second_sound, player, filename);
     spAddSoundFile (&third_sound, player, filename);
     .
     .
     .
     spAddSoundFile (&penultimate_sound, player, filename);
     spAddSoundFile (&final_sound, player, filename);`

2. Set a branch at the end of each sound to the beginning of the next one. Each sound has intrinsic markers for its beginning and ending.

     `spBranchAtMarker (first_sound, SP_MARKER_NAME_END,
     second_sound, SP_MARKER_NAME_BEGIN);
     spBranchAtMarker (second_sound, SP_MARKER_NAME_END,
     third_sound, SP_MARKER_NAME_BEGIN);
     .
     .
     .
     spBranchAtMarker (penultimate_sound, SP_MARKER_NAME_END,
     final_sound, SP_MARKER_NAME_BEGIN);`

   Because there is no branch at the end of the final sound, playback stops when the end of the final sound is reached.

   There is also a convenience macro for linking multiple sounds together that does the above `spBranchAtMarker()` calls:

     `spLinkSounds (first_sound, second_sound);
     spLinkSounds (second_sound, third_sound);
     .
     .
     .
     and so on.`

### Play a Sound File Continuously in a Loop

Substitute this step in the annotated example to create a seamless loop for the sound file and play that loop continuously.

- Set a branch at the end of the sound back to the beginning of the sound.

    `spBranchAtMarker (sound, SP_MARKER_NAME_END,
    sound, SP_MARKER_NAME_BEGIN);`

  There is also a convenience macro for this:

    `spLoopSound (sound);`
  Note that this example does not stop automatically because the branch at the end of the sound always goes back to the beginning of the same sound. The sound file continues to loop until you instruct it to stop. One way to do that is to call `spStop()` to stop the playback immediately, but this will more than likely cause an audible pop. To avoid this while still stopping almost immediately, you could use an envelope to ramp down the amplitude of the sample player instrument prior to calling `spStop()`. You can also cause playback to stop the next time the end of the sound is reached by clearing the branch at the end of the sound:

    `spStopAtMarker (sound, SP_MARKER_NAME_END);`
  You can do this at any time while playing the sound.