Sequenced Sound Playback

You will be concerned with three issues when using sequenced sound on the Nintendo 64:

- representing the sequence data

- representing the instruments or sounds that make up the sequence

- controlling the sequence playback

Representing the Sequence
The Audio Library supports two different sequence players. The first sequence player uses Type 0 MIDI sequences. Sequences are represented at runtime with the ALSeq structure. This structure encapsulates sequence data that conforms to the Standard MIDI Files 1.0 specification for Type 0 MIDI files. The Type 0 MIDI file format contains a time-ordered MIDI message that specifies music events. It is described in detail in the “Standard MIDI Files 1.0” specification published by the MIDI manufacturers association.

The second sequence player uses a compressed format of sequence data unique to the Nintendo 64. This format is detailed in Audio Formats chapter. Sequences are represented at runtime with the ALCSeq structure. Besides differences in the format of the data, the compressed MIDI sequence player handles loops in a different fashion and does not support markers.

To use a Type 0 MIDI sequence in your game, you must first initialize an ALSeq structure with alSeqNew(). To use the compressed MIDI sequence player, you first initialize an ALCSeq structure with alCSeqNew(). After initializing the ALSeq structure, you can perform sequence operations.

The alSeqNextEvent() call returns the MIDI event at a specified location in the sequence. The alSeqNewMarker() call creates a sequence position marker that can be used in conjunction with the Type 0 Sequence Player to set playback time and loop points. The convenience functions alSeqTicksToSec() and alSeqSecToTicks() convert between seconds and MIDI clock ticks.

Note: Normally, you won’t call alSeqNextEvent() directly, because it is called by the Sequence Player during sequence playback. The sequence calls are described in detail in the reference (man) pages. Brief descriptions are given in the following table.

Table 1 Sequence Functions

Type 0 MIDI Sequence Player Function | Compressed MIDI Sequence Player Function | Description
alSeqNew | alCSeqNew | Initializes the sequence control structure.
alCSeqNew | alCSeqNextEvent | Returns the next MIDI event from the sequence.
alSeqNewMarker | alCSeqNewMarker | Initializes a marker for a given event time.
alSeqGetLoc | alCSeqGetLoc | Sets a marker to the sequence’s current location.
alSeqSetLoc | alCSeqSetLoc | Sets the sequence to the location specified by the marker.
alSeqTicksToSec | alCSeqTicksToSec | Converts a time value from MIDI clock ticks to microseconds.
alSeqSecToTicks | alCSeqSecToTicks | Converts a time value from microseconds to MIDI clock ticks.

Representing Instruments
Instruments are represented at runtime by the ALBankFile structure. This structure describes the instruments that sound in response to an event in the sequence. Bank Files are composed of Banks; which are composed of Instruments; which themselves are composed of groups of Sounds, KeyMaps, Envelopes, and gain and pan information. The Bank File format is described in detail Section 19.1, "Bank Files."

To use a Bank File in your game, you must first create a runtime structure to represent it. This is accomplished with the alBnkfNew() function as described in the following table. Both sequence players use the same function call for this operation.

Table 2 Bank Functions

Type 0 MIDI Sequence Player Function | Compressed MIDI Sequence Player Function | Description
alBnkfNew | alBnkfNew | Initializes a collection of banks for use with a Sequence Player.

Playing Sequences
The Sequence Player is the mechanism by which the Nintendo 64 Audio Library plays back MIDI sequence files. It is responsible for allocating the hardware and software resources needed to play a sequence and for controlling the performance of the sequence data for the application.

Note: A Sequence Player can play only one sequence at a time.

There are certain steps you must take for your game to play a music sequence. The minimum steps needed to use the Type 0 MIDI sequence player are listed below. Using the compressed MIDI sequence player is identical, only you use the calls specific to the compressed MIDI sequence player.

1. Create and initialize the basic resources described in the section Generating Audio Output.

2. Initialize the sequence by using alSeqNew().

3. Copy the bank file’s .ctl file into RAM, and initialize the bank by using alBnkfNew().

4. Initialize the sequence player by using alSeqpNew().

5. Set the sequence player’s bank by using alSeqpSetBank().

6. Set the sequence player’s target sequence by using alSeqpSetSeq().

7. Play the sequence by using alSeqpPlay().

8. Stop the sequence when you are finished with it, by using alSeqpStop().

9. If the sequence player is no longer needed it can be removed from the Synthesis Driver’s client list by using alSeqpDelete().

Table 3 Sequence Player Functions

Type 0 MIDI Sequence Player Function | Compressed MIDI Sequence Player Function | Description
alSeqpNew | alCSPNew | Initializes a Sequence Player.
alSeqpDelete | alCSPDelete | Removes a Sequence Player from the Synthesis Driver’s client list.
alSeqpGetState | alCSPGetState | Returns the current state of the Sequence Player.
alSeqpSetBank | alCSPSetBank | Assigns a bank of instruments to the sequence.
alSeqpGetSequence | alCSPGetSequence | Gets a reference to the sequence that is currently bound to the Sequence Player.
alSeqpSetSequence | alCSPSetSequence | Makes the specified sequence the target sequence.
alSeqpPlay | alCSPPlay | Starts the target sequence playing.
alSeqpStop | alCSPStop | Stops the target sequence if it is playing.
alSeqpGetTempo | alCSPGetTempo | Returns the current playback tempo for the target sequence.
alSeqpSetTempo | alCSPSetTempo | Sets the current playback tempo of the target sequence.
alSeqpGetVol | alCSPGetVol | Returns the overall volume for the sequence.
alSeqpSetVol | alCSPSetVol | Sets the overall volume for the sequence.
alSeqpGetChlPan | alCSPGetChlPan | Gets the pan on the specified MIDI channel.
alSeqpSetChlPan | alCSPSetChlPan | Sets the pan for the specified MIDI channel.
alSeqpGetChlVol | alCSPGetChlVol | Gets the volume for the specified MIDI channel.
alSeqpSetChlVol | alCSPSetChlVol | Sets the volume for the specified MIDI channel.
alSeqpGetChlProgram | alCSPGetChlProgram | Returns the program assigned to the specified MIDI channel.
alSeqpSetChlProgram | alCSPSetChlProgram | Assigns the given program to the specified MIDI channel.
alSeqpGetChlFXMix | alCSPGetChlFXMix | Gets the wet/dry FX mix on the specified MIDI channel.
alSeqpSetChlFXMix | alCSPSetChlFXMix | Sets the wet/dry FX mix on the specified MIDI channel.
alSeqpGetChlPriority | alCSPGetChlPriority | Gets the priority value for the specified MIDI channel.
alSeqpSetChlPriority | alCSPSetChlPriority | Sets the priority value for the specified MIDI channel.
alSeqpLoop | (Not Supported) | Sets the loop points for the target sequence.
alSeqpSendMidi | alCSPSendMidi | Sends the specified MIDI message to the sequence player.

Loops in Sequence Players
The way in which loops are handled in the sequence players is different. When using the Type 0 MIDI sequence player, the programmer must create a marker at the loop start point, and a marker at the loop end point. Then the sequence can be looped between these two markers using alSeqpLoop(). Using the compressed MIDI sequence player, loops are constructed by the musician, in the tracks of the sequence by inserting controllers. (This is discussed in Section 18, "Audio Tools”). This method allows different loops for different tracks, and allows for nesting of loops.

Controllers in Sequence Players
The realtime controllers that the Sequence Player responds to are (control numbers in parenthesis): pan (10), volume (7), priority (16), sustain (64), and reverb amount (91). Note that because only one effects bus is supported, reverb amount is used to control effect amount no matter what the effect is.

The compact sequence player also uses controllers 102, 103, 104, and 105 for creating loops. Details of this are discussed in Section 18, "Audio Tools”.

Copyright © 1999 Nintendo of America Inc. All Rights Reserved Nintendo and N64 are registered trademarks of Nintendo Last Updated January, 1999