Allocating Amplitude


Mixer instruments add their DAC feeds together for each frame of the DAC. The maximum value of the left or right result for each frame can be no larger than 0x7FFF. If it is larger, it is truncated to 0x7FFF, which can cause horrible sounds to issue forth from the user's headphones or stereo system.

To avoid clipping at the DAC, it helps to think of the final DAC amplitude of 0x7FFF as a system resource, as system amplitude. Each instrument that creates an audio signal can have a fraction of the system amplitude as a maximum instrument amplitude. The instrument should not exceed that instrument maximum so the system maximum cannot be exceeded.

If you can be sure that only one instrument at a time is fed into the DAC (a virtual impossibility on a multitasking system), then you can crank the sole instrument's maximum amplitude up to 0x7FFF without worry. However, you should try to limit an instrument's maximum amplitude to a fraction of the system amplitude so that other instruments can be added safely to the DAC without distortion. For example, if you are playing four-note chords with four instruments, then each instrument should be set to play no louder than 0x7FFF/4. Because each instrument plays at only a fourth of system-maximum amplitude, then when all four instruments play their loudest, their total will not exceed 0x7FFF.

Adjusting Amplitude in a Mixer

A mixer instrument is an ideal place to adjust individual instrument amplitudes. A mixer has a set of inputs that can be connected to instruments, one input per mono instrument, two inputs per stereo instrument. Each input has two knobs associated with it: a left gain knob and a right gain knob. For example, Input0 of the instrument mixer8x2.dsp is controlled by the knobs LeftGain0and RightGain0.

Each signal coming into the mixer is split and fed to both the left and right DAC outputs of the mixer. The signal's control knobs control how much of the signal appears in the left channel and how much appears in the right channel. When the left knob is set to its maximum value (0x7FFF), the signal appears at its original amplitude in the left DAC channel. And when the right knob is set to its maximum value, the signal appears at its original amplitude in the right DAC channel.

The ratio of a signal's knob settings determines the balance of the signal in the stereo output. For example, if both left and right knobs are set to maximum, the signal appears at its original strength in both channels. If the left knob is set to maximum and the right knob is set to 0, the signal appears at its original strength only in the left channel. And if the right knob is set to three quarters and the left knob is set to one quarter, the signal appears balanced off to the right.

Note that the mixer does not amplify incoming signals. If a knob is set to maximum value, it simply passes the signal through at its incoming amplitude. A mixer does attenuate signals, though. When a knob is set below maximum, the incoming signal is reduced by that amount. For example, a knob set to half maximum (0x4000) reduces the incoming signal by half of its amplitude.

The separate signals mixed into the mixer's left and right channels are added together before they are added to any other mixer input to the DAC channels. Therefore, it is possible for a mixer to exceed maximum amplitude internally, even before the signal goes to the DAC. Make sure that the total of knob settings for one side (left or right) does not exceed 0x7FFF. If the total goes over, the signals are clipped within the mixer. If the total stays under, the added signals never exceed maximum amplitude. For example, a mixer accepting three instrument inputs might want to split amplitude equally for left channel knobs, so each input's left knob is set to 0x7FFF/3. It can do the same for the right channel knobs.

Allocating System Amplitude

A task can easily balance instruments within a mixer because the task controls the amplitude of all input to the mixer. A task cannot control the final mix at the DAC channels, however, because it has no idea what other tasks may have mixers adding their inputs to the channels. To help tasks live amiably together at the DAC, the Audio folio provides a simple system amplitude allocation system.

When the Audio folio is first opened, it establishes a value that keeps track of system amplitude available to different tasks. The value starts at 0x7FFF, the maximum system amplitude. When a task wants to add a mixer's output to the DAC channels, the task can ask the Audio folio to allocate some of the system amplitude to the task so the task can use it for the mixer's final output. When the Audio folio allocates the amplitude to the task, it subtracts the allocated amplitude from the available system amplitude. Each task setting up a mixer can ask for allocated amplitude until no system amplitude remains.

Amplitude allocation is strictly on the honor system. A task can set up a mixer without allocating amplitude if it is rude enough to do so, and a task that allocates amplitude can ignore it and exceed the allocated maximum when it sets up a mixer. An honorable task always allocates amplitude before it sets up a mixer and makes sure that the mixer output for each channel does not exceed the allocated amplitude.

Tasks that do not allocate amplitude and stay within the limitations of allocated amplitude will mess up audio for everyone and crank out horrendous sounds through 3DO earphones and speakers everywhere.

To allocate amplitude, use this call:

int32 AllocAmplitude( int32 Amplitude )
The call accepts a single argument: Amplitude, the desired amount of system amplitude to be allocated. Amplitude can be a value from 0(none of the system amplitude, in which case, why use the call) to 0x7FFF (which asks for all of the system's amplitude). When executed, AllocAmplitude() checks to see if the desired amount of amplitude is available and, if it is, allocates the amplitude to the task and subtracts the allocated amplitude from the system total. If there is not enough system amplitude to satisfy the allocation request, the call allocates whatever system amplitude is left and sets system amplitude to 0.

AllocAmplitude() returns the amount of amplitude allocated to the task, an amount that can range from the amount requested to 0.

Freeing System Amplitude

When a task no longer requires amplitude that it allocated (it might, for example, delete a mixer instrument), the task should always free the amplitude so that other tasks and mixers can use it. To do so, use this call:

Err FreeAmplitude( int32 Amplitude )
The call accepts a single argument: Amplitude, the desired amount of allocated amplitude to give back to the system. When executed, FreeAmplitude() adds the amount of freed amplitude back to the total system amplitude available. If successful, it returns 0. If unsuccessful, it returns a negative value (an error code).

Playing Instruments, shows you how to use the instruments you set up.