Q&A- Sequence Player

QA1 About alCSPLoop(), etc.
QA2 Loop playback
QA3 Instruments
QA4 Sequence players
QA5 Tremolo
QA6 The sounds of certain parts is strange
QA7 Differences between two sequence players
QA8 The stop time in asCSPStop() is over 100 frames
QA9 What does ASSERTION FAULT:../audio.c, 105:"samples>=0":"samples<=AL_MAX_RSP_SAMPLES" mean?
QA10 Processing time slows down when I increase a sequence player's number of logical voices
QA11 How do I loop sequence data?
QA12 What kind of loop information is included in the sequence data?
QA13 I want to stop looped sequence data without making it loop.
QA14 Looping at different timing from that in the sequence data
QA15 My sound effects are disabled.

Q1 There don't seem to be any functions for compressed MIDI files that correspond with the alSeqLoop() for setting up sequence loops. Will (something like alCSPLoop()) be provided in the future?

A1 Probably not. There is no function for performing loop control with an external function such as Seqplayer, which controls normal MIDI sequences. Instead, extremely detailed control is possible. It is possible to create up to 128 sequential or nested loops per track. The loop setting in alCSeqPlayer mentioned in your question is performed on the MIDI data side. You can use everything up to the undefined control routine (102-105), but you should refer to Chapter 20, "MIDI Files," in the N64 Online Programming Manual.

Q2 When playing back a loop, can the loop start point be set to any other than the file head? If it can be done, is processing needed, such as resetting the loop start point with a program change, or the like?

A2 Control changes can be freely inserted anywhere. It is also possible to loop any range other than the file head. You should be able to do this without any program changes, but it is recommended that these be inserted when the amount of memory and/or the processing load are not concerns.


Q3 Can the bend range in the AlInstrument structure be set in semi-tone units? What is the default value if this is not specified?

A3 The bend range is set in cent units. Since the maximum value is in the 16 bit range, up to 32,767 can be set, but it would probably be safest to stop it at the one octave unit. The default value on the player side is 200 cents (one full tone). The source code that we have is the version that does not reflect the bank settings (it stays at 200 cents no matter what is written), but it may still be this way.


Q4 When I play a sequence with a sequence player, the rhythm sometimes speeds up and slows down. What causes this and how can I avoid it?

A4 Assuming that your sequence player is compact, here are some possibilities.

  1. Check to see if processing is stopping.

  2. Use alAudioFrame() to check if the right number of samples is being given for each frame.

  3. Are there incorrect commands embedded in the sequence? This is a bug.

  4. If the timebase of the original sequence is 480, is the included delta time too short (1, etc.)?


Q5 How do I apply tremolo?

A5 All of the tremolo types (1-4) are available (confirm with Ver2.0c). However, since the change time is slower than would be ideal, try setting the tremoloRate value high and changing the variable definition in the sample updataOsc from

ALMicrotime deltatime = AL_USEC_PER_FRAME


ALMicrotime deltatime = AL_USEC_PER_FRAME / 8

At this time, there is no bug in which a lot of processing time is used up when anything other than a square wave tremolo is used. In addition, since setting the delay time to 0 will be seen as "no change," set Delay to 1 or more.


Q6 When the BMG is played, sometimes certain parts (instruments) will not play, or the tempo will change. Why do you think that is?

A6 Various causes are considered in connection with these symptoms.

  1. Improper virtual voices or physical voices.
    If the same number of virtual voices as there are physical voices, are defined, the voices may not play back if the number of voices momentarily increases. In this case, if you only change the number of virtual voices to a sufficiently large value, when there are too many voices, those parts with the lowest priority will not be played and this will not be noticed overall. Naturally, it is important that the main parts be given higher priority.

    As for processing time, nothing can be done if the MAX is exceeded. You could try smoothing out the processing on the data side so that the timing of program changes and note-on processing are not overlapped in the same frame. Beyond that, if the game frame is two frames, you should measure the MAX value in two continuous frames. I don't think there are any data which would bring about the worst case scenario of two frames running.

  2. Improper buffers.
    Following is a list of the buffers. Try tuning each of them so that they are optimized.

    Sample DMA Buffers, Audio Output Buffers, Command List Buffers, Synthesizer Updates, Sequencer Events, Reverb Delay Size, Sequence Buffer, Bank Ctl Buffer, Audio Thresd Stack, Audio Heap

  3. The message queue buffer osPistartDma, which performs, DMA has overflowed.
    The buffer that receives the osPiStartDma(, , , , , &dmaMessageQ) message queue, which performs DMA, has been eaten up with graphics, etc., and may have overflowed. Try rethinking the entire DMA system and changing the values accordingly.


Q7 What are the differences in the usage methods for the standard sequence player and the compact sequence player?

A7 The standard sequence player plays MIDI sequences formatted to comply with the standard MIDI file 1.0 specification for type 0 MIDI files. In contrast to this, the compact sequence player plays sequence data of the proprietary N64 compressed MIDI format. There are 3 actual differences between the compact player and the standard player:

  1. Function syntax
  2. Format of data handled
  3. Loop processing method

The loop processing method for the compact player consists of the musician constructing the loop by inserting a controller in the sequence track, while the method for the standard player comprises the programmer creating one marker each for the start point and the end point of the loop, then causing the sequence to loop between the two markers using the alSeqpLoop() function.


Q8 The stop time in alCSPStop() is over 100 frames.

A8 I couldn't find any reason in the sequence player code for the stop time to be this length.

As a suggestion, is the value for Event_count too small? For example, this value is a buffer for collecting the event changes that are generated with time, such as alCSPPlay and Stop. The inability to stop may be due to this being insufficient.


Q9 When I start up 5 sequence players and repeatedly PLAY and STOP a sound, the error

ASSERTION FAULT:../audio.c, 105:"samples>=0":"samples<=AL_MAX_RSP_SAMPLES"

occurs. How do I handle this?

A9 The number of ABI command samples which can be processed at once by the RSP is set at 160 in the aspMain microcode. It seems that this error is occurring because this processing sample count is being exceeded for some reason. Check to see if the task-related buffers have been destroyed.


Q10 The processing time slows down if I increase the number of logical voices in the sequence player.

A10 Check the following 3 items.

  1. When the number of physical voices in the compact sequence player is set to 12, the number of sounds synthesized must be 12 or fewer.

  2. If the number of logical voices in the compact sequence player is set to 32, up to 32 sounds, including the releases, can be layered at any moment in one sequence. However, the number of these 32 sounds which actually can be voiced is limited to the number of logical voices set by the synthesizer driver.

  3. The number of logical voices in the synthesizer driver can be set to any value.

Two things can be said from the above:

  1. "the only thing that increases, even if the number of logical voices is increased, is the processing time consumed by the dynamic allocation"

  2. "the compact sequence player does not use the logical voices of the synthesizer driver."

The majority of CPU processing time consumed by audio exists in the work of assembling command lists for the various physical voices. Sequence processing and the allocation of physical voices from the logical voices themselves are not much of a problem. The fact that "the processing time is slower when the number of logical voices is set to 16 than when it is set to 12," is not due to the number of physical voices being 16, but is probably "because the 12 voices, which until now were not all being voiced, are now always being voiced because voids in the logical voice processing have disappeared."

Could it be that processing has slowed not because the number of logical voices was increased, but rather be that it has become slower than it has been because the voices which essentially should have been processed now actually are being processed? If there are not enough logical voices, voices will not be physically generated regardless of the priority of the voices turned ON because they are in a state in which they cannot be candidates for generation (=no free voices).


Q11 How do I loop sequence data?

A11 When creating the MIDI data, insert a "control change " at the start position and the end position of the loop. The control numbers are

loopstart       102
loopend         103
loopcount       104 or 105

Control changes have a 7-bit value as the argument, consisting of the loop ID number for loopstart and loopend, or the number of loop iterations for loopcount. With control 105, 128 is added to the setting and set as the loop iterations. Since the default is for infinite loop iterations, data can be simply created in which a song intro will be played and then a loop segment will infinitely cycle by setting the following:

Song intro

Control Change 102,0

Song loop segment

Control Change 103,0

However, since control changes are commands given in channel units, commands must be embedded for all of the channels being used by the sequence.

Doubling is permitted if the ID numbers are different from the channel. See the manual regarding more complex loops.


Q12 What kind of loop information is included in the sequence data?

A12 This is explained in detail in Chapter 20, Section 5, ""Loops in Sequences," in the N64 Online Programming Manual.


Q13 I want to stop looped sequence data without making it loop.

A13 Check the loop status on the software side by embedding a dummy track for checking the loop.


Q14 Looping at different timing from that in the sequence data

A14 If the compact sequence player is used, the loop will be embedded in the data using entirely MIDI commands, so that the player will automatically perform them, without requiring any operation on the program side.

Once again, check the control number of the following control changes in the MIDI file.

loopstart       102
loopend         103
loopcount       104 or 105


Q15 I am using NuSystem, but the effects are completely disabled even when I execute nuAuSeqPlayerSetChlFXMix() (for all MIDI channels).

Even Pan has no effect on the sequence when I use the above method.

A15 Do you have reverb depth and/or pan control changes embedded in the MIDI data?

Since the controller has priority over settings from functions, this could be preventing your effects from having any effect.