After you have allocated the sound hardware and declared all your sounds,
you're ready to start playback. This is done with a call to
AHI_ControlAudioA()
, with the AHIC_Play
tag set to
TRUE
. When this function returns the PlayerFunc (see
AHI_AllocAudioA()
) is active, and the audio driver is feeding
silence to the sound hardware.
All you have to do now is to set the desired sound, it's frequency and
volume. This is done with AHI_SetSound()
, AHI_SetFreq()
and
AHI_SetVol()
. Make sure the AHISF_IMM
flag is set for all
these function's flag argument. And don't try to modify a channel
that is out of range! If you have allocated 4 channels you may only modify
channels 0-3.
The sound will not start until both AHI_SetSound()
and
AHI_SetFreq()
has been called. The sound will play even if
AHI_SetVol()
was not called, but it will play completely silent. If
you wish to temporary stop a sound, set its frequency to 0. When you
change the frequency again, the sound will continue where it were.
When the sound has been started it will play to the end and then repeat.
In order to play a one-shot sound you have use the AHI_PlayA()
function, or install a sound interrupt using the AHIA_SoundFunc
tag
with AHI_AllocAudioA()
. For more information about using sound
interrupts, see below.
A little note regarding AHI_SetSound()
: Offset is the first
sample that will be played, both when playing backwards and forwards. This
means that if you call AHI_SetSound()
with offset 0 and
length 4, sample 0,1,2 and 3 will be played. If you call
AHI_SetSound()
with offset 3 and length -4,
sample 3,2,1 and 0 will be played.
Also note that playing very short sounds will be very CPU intensive, since there are many tasks that must be done each time a sound has reached its end (like starting the next one, calling the SoundFunc, etc.). Therefore, it is recommended that you "unroll" short sounds a couple of times before you play them. How many times you should unroll? Well, it depends on the situation, of course, but try making the sound a thousand samples long if you can. Naturally, if you need your SoundFunc to be called, you cannot unroll.
Some changes has been made since earlier releases. One-shot sounds and
sounds with only one loop segment can now be played without using sample
interrupts. This is possible because one of the restrictions regarding the
AHISF_IMM
flag has been removed.
The AHISF_IMM
flag determines if AHI_SetSound()
,
AHI_SetFreq()
and AHI_SetVol()
should take effect immediately
or when the current sound has reached its end. The rules for this flags
are:
What does this mean? It means that if all you want to do is to play a
one-shot sound from inside a PlayerFunc, you can do that by first
calling AHI_SetSound()
, AHI_SetFreq()
and AHI_SetVol()
with AHISF_IMM
set, and then use AHI_SetSound(ch, AHI_NOSOUND,
0, 0, actrl, 0L)
to stop the sound when it has reached the end. You can
also set one loop segment this way.
AHI_PlayA()
was added in AHI version 4, and combines
AHI_SetSound()
, AHI_SetFreq()
and AHI_SetVol()
into
one tag-based function. It also allows you to set one loop and play
one-shot sounds.
To play a sound with more than one loop segment or ping-pong looping, a sample interrupt needs to be used. AHI's SoundFunc works like Paula's interrupts and is very easy to use.
The SoundFunc hook will be called with an AHIAudioCtrl
structure as object and an AHISoundMessage
structure as message.
ahism_Channel
indicates which channel caused the hook to be called.
An example SoundFunc which handles the repeat part of an instrument can look like this (SAS/C code):
__asm __saveds ULONG SoundFunc(register __a0 struct Hook *hook, register __a2 struct AHIAudioCtrl *actrl, register __a1 struct AHISoundMessage *chan) { if(ChannelDatas[chan->ahism_Channel].Length) AHI_SetSound(chan->ahism_Channel, 0, (ULONG) ChannelDatas[chan->ahism_Channel].Address, ChannelDatas[chan->ahism_Channel].Length, actrl, NULL); else AHI_SetSound(chan->ahism_Channel, AHI_NOSOUND, NULL, NULL, actrl, NULL); return NULL; }
This example is from an old version of the AHI NotePlayer for
DeliTracker 2. ChannelDatas
is an array where the start and
length of the repeat part is stored. Here, a repeat length of zero
indicates a one-shot sound. Note that this particular example only uses
one sound (0). For applications using multiple sounds, the sound number
would have to be stored in the array as well.
Once again, note that the AHISF_IMM
flag should never be
set in a SoundFunc hook!
Starting with V4, AHI_SetVol()
can take both negative volume and
pan parameters. If you set the volume to a negative value, the sample
will, if the audio mode supports it, invert each sample before playing. If
pan is negative, the sample will be encoded to go to the surround speakers.
Go to the first, previous, next, last section, table of contents.