2 AHI - Hardware independent audio subsystem
3 Copyright (C) 2017 The AROS Dev Team
4 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
24 #include <exec/memory.h>
25 #include <utility/tagitem.h>
26 #include <proto/exec.h>
27 #include <proto/utility.h>
29 #define __NOGLOBALIFACE__
30 #include <proto/ahi.h>
32 #undef __NOGLOBALIFACE__
33 #include <proto/ahi_sub.h>
38 #include "effectinit.h"
42 #define IAHIsub audioctrl->ahiac_IAHIsub
45 /******************************************************************************
46 ** AHI_SetVol *****************************************************************
47 ******************************************************************************/
49 /***** ahi.device/AHI_SetVol ***********************************************
52 * AHI_SetVol -- set volume and stereo panning for a channel
55 * AHI_SetVol( channel, volume, pan, audioctrl, flags );
58 * void AHI_SetVol( UWORD, Fixed, sposition, struct AHIAudioCtrl *,
62 * Changes the volume and stereo panning for a channel.
65 * channel - The channel to set volume for.
66 * volume - The desired volume. Fixed is a LONG fixed-point value with
67 * 16 bits to the left of the point and 16 to the right
68 * (typedef LONG Fixed; from IFF-8SVX docs).
69 * Maximum volume is 1.0 (0x10000L) and 0.0 (0x0L) will turn off
70 * this channel. Note: The sound will continue to play, but you
71 * wont hear it. To stop a sound completely, use AHI_SetSound().
72 * Starting with V4 volume can also be negative, which tells AHI
73 * to invert the samples before playing. Note that all drivers
74 * may not be able to handle negative volume. In that case the
75 * absolute volume will be used.
76 * pan - The desired panning. sposition is the same as Fixed
77 * (typedef Fixed sposition; from IFF-8SVX.PAN docs).
78 * 1.0 (0x10000L) means that the sound is panned all the way to
79 * the right, 0.5 (0x8000L) means the sound is centered and 0.0
80 * (0x0L) means that the sound is panned all the way to the left.
81 * Try to set Pan to the 'correct' value even if you know it has no
82 * effect. For example, if you know you use a mono mode, set pan to
83 * 0.5 even if it does not matter.
84 * Starting with V4 pan can also be negative, which tells AHI to
85 * use the surround speaker for this channel. Note that all drivers
86 * may not be able to handle negative pan. In that case the absolute
88 * audioctrl - A pointer to an AHIAudioCtrl structure.
89 * flags - Only one flag is defined
90 * AHISF_IMM - Set this flag if this command should take effect
91 * immediately. If this bit is not set, the command will not
92 * take effect until the current sound is finished. MUST NOT
93 * be set if called from a SoundFunc. See the programming
94 * guidelines for more information about this flag.
101 * It is safe to call this function from an interrupt.
103 * Negative volume or negative pan may use more CPU time than positive.
105 * Using both negative volume and negative pan will play the inverted
106 * sound on the surround speaker.
111 * AHI_SetEffect(), AHI_SetFreq(), AHI_SetSound(), AHI_LoadSound()
114 ****************************************************************************
119 _AHI_SetVol ( UWORD channel
,
122 struct AHIPrivAudioCtrl
* audioctrl
,
124 struct AHIBase
* AHIBase
)
126 struct AHIChannelData
*cd
;
127 struct Library
*AHIsubBase
;
130 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_ALL
)
132 Debug_SetVol(channel
, volume
, pan
, audioctrl
, flags
);
135 AHIsubBase
= audioctrl
->ahiac_SubLib
;
137 rc
= AHIsub_SetVol(channel
, volume
, pan
, &audioctrl
->ac
, flags
);
139 if(audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
140 || rc
!= AHIS_UNKNOWN
)
142 return 0; /* We're done! */
145 cd
= &audioctrl
->ahiac_ChannelDatas
[channel
];
147 if((audioctrl
->ac
.ahiac_Flags
& AHIACF_VOL
) == 0)
149 volume
= volume
& 0x10000; /* |volume|=0 or 0x10000 */
152 if((audioctrl
->ac
.ahiac_Flags
& AHIACF_PAN
) == 0)
154 pan
= (channel
& 1) << 16; /* pan = 0 or 0x10000 */
157 AHIsub_Disable(&audioctrl
->ac
);
159 cd
->cd_NextVolumeLeft
= ((volume
>> 1) * ((0x10000 - abs(pan
)) >> 1)) >> (16 - 2);
160 cd
->cd_NextVolumeRight
= ((volume
>> 1) * (pan
>> 1)) >> (16 - 2);
162 SelectAddRoutine( cd
->cd_NextVolumeLeft
,
163 cd
->cd_NextVolumeRight
,
166 &cd
->cd_NextScaleLeft
,
167 &cd
->cd_NextScaleRight
,
168 (ADDFUNC
**) &cd
->cd_NextAddRoutine
);
170 if(flags
& AHISF_IMM
)
172 cd
->cd_DelayedVolumeLeft
= cd
->cd_NextVolumeLeft
;
173 cd
->cd_DelayedVolumeRight
= cd
->cd_NextVolumeRight
;
175 SelectAddRoutine( cd
->cd_DelayedVolumeLeft
,
176 cd
->cd_DelayedVolumeRight
,
179 &cd
->cd_DelayedScaleLeft
,
180 &cd
->cd_DelayedScaleRight
,
181 (ADDFUNC
**) &cd
->cd_DelayedAddRoutine
);
183 /* Enable anti-click routine */
184 cd
->cd_AntiClickCount
= audioctrl
->ac
.ahiac_AntiClickSamples
;
186 if( ( flags
& AHISF_NODELAY
) ||
187 ( cd
->cd_AntiClickCount
== 0 ) ||
188 !cd
->cd_FreqOK
|| !cd
->cd_SoundOK
)
190 cd
->cd_VolumeLeft
= cd
->cd_DelayedVolumeLeft
;
191 cd
->cd_VolumeRight
= cd
->cd_DelayedVolumeRight
;
192 cd
->cd_ScaleLeft
= cd
->cd_DelayedScaleLeft
;
193 cd
->cd_ScaleRight
= cd
->cd_DelayedScaleRight
;
194 cd
->cd_AddRoutine
= cd
->cd_DelayedAddRoutine
;
196 cd
->cd_AntiClickCount
= 0;
200 cd
->cd_VolDelayed
= TRUE
;
204 AHIsub_Enable(&audioctrl
->ac
);
210 /******************************************************************************
211 ** AHI_SetFreq ****************************************************************
212 ******************************************************************************/
214 /***** ahi.device/AHI_SetFreq **********************************************
217 * AHI_SetFreq -- set frequency for a channel
220 * AHI_SetFreq( channel, freq, audioctrl, flags );
223 * void AHI_SetFreq( UWORD, ULONG, struct AHIAudioCtrl *, ULONG );
226 * Sets the playback frequency for a channel.
229 * channel - The channel to set playback frequency for.
230 * freq - The playback frequency in Hertz. Can also be AHI_MIXFREQ,
231 * which is the current mixing frequency, or 0 to temporary stop
232 * the sound (it will restart at the same point when its frequency
234 * audioctrl - A pointer to an AHIAudioCtrl structure.
235 * flags - Only one flag is defined
236 * AHISF_IMM - Set this flag if this command should take effect
237 * immediately. If this bit is not set, the command will not
238 * take effect until the current sound is finished. MUST NOT
239 * be set if called from a SoundFunc. See the programming
240 * guidelines for more information about this flag.
247 * It is safe to call this function from an interrupt.
252 * AHI_SetEffect(), AHI_SetSound(), AHI_SetVol(), AHI_LoadSound()
254 ****************************************************************************
259 _AHI_SetFreq ( UWORD channel
,
261 struct AHIPrivAudioCtrl
* audioctrl
,
263 struct AHIBase
* AHIBase
)
265 struct AHIChannelData
*cd
;
266 struct Library
*AHIsubBase
;
270 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_ALL
)
272 Debug_SetFreq(channel
, freq
, audioctrl
, flags
);
275 AHIsubBase
= audioctrl
->ahiac_SubLib
;
277 rc
= AHIsub_SetFreq(channel
, freq
, &audioctrl
->ac
, flags
);
279 if(audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
280 || rc
!= AHIS_UNKNOWN
)
282 return 0; /* We're done! */
285 cd
= &audioctrl
->ahiac_ChannelDatas
[channel
];
289 cd
->cd_NextFreqOK
= FALSE
;
295 cd
->cd_NextFreqOK
= TRUE
;
297 if(freq
== AHI_MIXFREQ
)
311 add
= ((freq
<< 16) / audioctrl
->ac
.ahiac_MixFreq
) << shift
;
315 AHIsub_Disable(&audioctrl
->ac
);
317 cd
->cd_NextAdd
= (Fixed64
) add
<< 16;
319 if(flags
& AHISF_IMM
)
321 cd
->cd_DelayedAdd
= cd
->cd_NextAdd
;
322 cd
->cd_DelayedFreqOK
= cd
->cd_NextFreqOK
;
324 // cd->cd_Samples is also calculated when it actually happens¹...
326 cd
->cd_DelayedSamples
= CalcSamples( cd
->cd_DelayedAdd
,
328 cd
->cd_DelayedLastOffset
,
329 cd
->cd_DelayedOffset
);
331 /* Enable anti-click routine */
332 cd
->cd_AntiClickCount
= audioctrl
->ac
.ahiac_AntiClickSamples
;
334 if( ( flags
& AHISF_NODELAY
) ||
335 ( cd
->cd_AntiClickCount
== 0 ) ||
336 !cd
->cd_FreqOK
|| !cd
->cd_SoundOK
)
338 cd
->cd_Add
= cd
->cd_DelayedAdd
;
339 cd
->cd_FreqOK
= cd
->cd_DelayedFreqOK
;
341 // ¹) Unless we're not using any delay, in which case it's recalculated
344 cd
->cd_Samples
= CalcSamples( cd
->cd_Add
,
349 cd
->cd_AntiClickCount
= 0;
353 cd
->cd_FreqDelayed
= TRUE
;
357 AHIsub_Enable(&audioctrl
->ac
);
363 /******************************************************************************
364 ** AHI_SetSound ***************************************************************
365 ******************************************************************************/
367 /***** ahi.device/AHI_SetSound *********************************************
370 * AHI_SetSound -- set what sound to play for a channel
373 * AHI_SetSound( channel, sound, offset, length, audioctrl, flags );
374 * D0:16 D1:16 D2 D3 A2 D4
376 * void AHI_SetSound( UWORD, UWORD, ULONG, LONG,
377 * struct AHIAudioCtrl *, ULONG );
380 * Sets a sound to be played on a channel.
383 * channel - The channel to set sound for.
384 * sound - Sound to be played, or AHI_NOSOUND to turn the channel off.
385 * offset - Only available if the sound type is AHIST_SAMPLE or
386 * AHIST_DYNAMICSAMPLE. Must be 0 otherwise.
387 * Specifies an offset (in samples) where the playback will begin.
388 * If you wish to play the whole sound, set offset to 0.
389 * length - Only available if the sound type is AHIST_SAMPLE or
390 * AHIST_DYNAMICSAMPLE. Must be 0 otherwise.
391 * Specifies how many samples that should be played. If you
392 * wish to play the whole sound forwards, set offset to 0 and length
393 * to either 0 or the length of the sample array. You may not set
394 * length to 0 if offset is not 0! To play a sound backwards, just
395 * set length to a negative number.
396 * audioctrl - A pointer to an AHIAudioCtrl structure.
397 * flags - Only one flag is defined
398 * AHISF_IMM - Set this flag if this command should take effect
399 * immediately. If this bit is not set, the command will not
400 * take effect until the current sound is finished. MUST NOT
401 * be set if called from a SoundFunc. See the programming
402 * guidelines for more information about this flag.
409 * It is safe to call this function from an interrupt.
411 * If offset or length is not zero, make sure you do not exceed the
417 * AHI_SetEffect(), AHI_SetFreq(), AHI_SetVol(), AHI_LoadSound()
419 ****************************************************************************
424 _AHI_SetSound ( UWORD channel
,
428 struct AHIPrivAudioCtrl
* audioctrl
,
430 struct AHIBase
* AHIBase
)
432 struct AHIChannelData
*cd
;
433 struct AHISoundData
*sd
;
434 struct Library
*AHIsubBase
;
437 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_ALL
)
439 Debug_SetSound(channel
, sound
, offset
, length
, audioctrl
, flags
);
442 AHIsubBase
= audioctrl
->ahiac_SubLib
;
444 rc
= AHIsub_SetSound(channel
, sound
, offset
, length
, &audioctrl
->ac
, flags
);
446 if(audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
447 || rc
!= AHIS_UNKNOWN
)
449 return 0; /* We're done! */
452 cd
= &audioctrl
->ahiac_ChannelDatas
[channel
];
453 sd
= &audioctrl
->ahiac_SoundDatas
[sound
];
455 AHIsub_Disable(&audioctrl
->ac
);
457 if(sound
== AHI_NOSOUND
)
459 cd
->cd_NextSoundOK
= FALSE
;
461 if(flags
& AHISF_IMM
)
463 cd
->cd_EOS
= TRUE
; /* Signal End-Of-Sample */
464 cd
->cd_SoundOK
= FALSE
;
467 else if(sd
->sd_Type
!= AHIST_NOTYPE
) /* This is a user error, shouldn't happen! */
469 if(length
== 0) length
= sd
->sd_Length
;
471 cd
->cd_NextDataStart
= sd
->sd_Addr
;
472 cd
->cd_NextType
= sd
->sd_Type
;
473 cd
->cd_NextOffset
= (Fixed64
) offset
<< 32 ;
475 cd
->cd_NextSoundOK
= TRUE
;
479 cd
->cd_NextType
|= AHIST_BW
;
480 cd
->cd_NextLastOffset
= (Fixed64
) ( offset
+ length
+ 1 ) << 32;
481 // cd->cd_NextOffset |= 0xffffffffLL;
482 *(ULONG
*) ((char*) (&cd
->cd_NextOffset
)+4) = 0xffffffffUL
;
486 #if !defined( __mc68000__ )
487 cd
->cd_NextLastOffset
= ( (Fixed64
) ( offset
+ length
- 1 ) << 32 )
488 | (Fixed64
) 0xffffffffLL
;
490 // Fix for m68k compiler bug! :-(
491 *(ULONG
*) &cd
->cd_NextLastOffset
= offset
+ length
- 1;
492 *(ULONG
*) ((char*) (&cd
->cd_NextLastOffset
)+4) = 0xffffffffUL
;
495 /* Low cd->cd_NextOffset already 0 */
498 SelectAddRoutine( cd
->cd_NextVolumeLeft
,
499 cd
->cd_NextVolumeRight
,
502 &cd
->cd_NextScaleLeft
,
503 &cd
->cd_NextScaleRight
,
504 (ADDFUNC
**) &cd
->cd_NextAddRoutine
);
506 if(flags
& AHISF_IMM
)
508 cd
->cd_DelayedOffset
= cd
->cd_NextOffset
;
509 cd
->cd_DelayedFirstOffsetI
= cd
->cd_NextOffset
>> 32; /* for linear interpol. */
510 cd
->cd_DelayedLastOffset
= cd
->cd_NextLastOffset
;
511 cd
->cd_DelayedDataStart
= cd
->cd_NextDataStart
;
512 cd
->cd_DelayedType
= cd
->cd_NextType
;
513 cd
->cd_DelayedSoundOK
= cd
->cd_NextSoundOK
;
515 SelectAddRoutine( cd
->cd_DelayedVolumeLeft
,
516 cd
->cd_DelayedVolumeRight
,
519 &cd
->cd_DelayedScaleLeft
,
520 &cd
->cd_DelayedScaleRight
,
521 (ADDFUNC
**) &cd
->cd_DelayedAddRoutine
);
523 cd
->cd_DelayedSamples
= CalcSamples( cd
->cd_DelayedAdd
,
525 cd
->cd_DelayedLastOffset
,
526 cd
->cd_DelayedOffset
);
528 /* Enable anti-click routine */
529 cd
->cd_AntiClickCount
= audioctrl
->ac
.ahiac_AntiClickSamples
;
531 if( ( flags
& AHISF_NODELAY
) ||
532 ( cd
->cd_AntiClickCount
== 0 ) ||
533 !cd
->cd_FreqOK
|| !cd
->cd_SoundOK
)
535 cd
->cd_StartPointL
= 0;
536 cd
->cd_StartPointR
= 0;
538 cd
->cd_Offset
= cd
->cd_DelayedOffset
;
539 cd
->cd_FirstOffsetI
= cd
->cd_DelayedFirstOffsetI
;
540 cd
->cd_LastOffset
= cd
->cd_DelayedLastOffset
;
541 cd
->cd_DataStart
= cd
->cd_DelayedDataStart
;
542 cd
->cd_Type
= cd
->cd_DelayedType
;
543 cd
->cd_SoundOK
= cd
->cd_DelayedSoundOK
;
544 cd
->cd_ScaleLeft
= cd
->cd_DelayedScaleLeft
;
545 cd
->cd_ScaleRight
= cd
->cd_DelayedScaleRight
;
546 cd
->cd_AddRoutine
= cd
->cd_DelayedAddRoutine
;
547 cd
->cd_Samples
= cd
->cd_DelayedSamples
;
548 cd
->cd_AntiClickCount
= 0;
552 cd
->cd_SoundDelayed
= TRUE
;
555 cd
->cd_EOS
= TRUE
; /* Signal End-Of-Sample */
559 AHIsub_Enable(&audioctrl
->ac
);
565 /******************************************************************************
566 ** AHI_SetEffect **************************************************************
567 ******************************************************************************/
569 /***** ahi.device/AHI_SetEffect ********************************************
572 * AHI_SetEffect -- set effect
575 * error = AHI_SetEffect( effect, audioctrl );
578 * ULONG AHI_SetEffect( APTR, struct AHIAudioCtrl * );
581 * Selects an effect to be used, described by a structure.
584 * effect - A pointer to an effect data structure, as defined in
585 * <devices/ahi.h>. The following effects are defined:
586 * AHIET_MASTERVOLUME - Changes the volume for all channels. Can
587 * also be used to boost volume over 100%.
588 * AHIET_OUTPUTBUFFER - Gives READ-ONLY access to the mixed output.
589 * Can be used to show nice scopes and VU-meters.
590 * AHIET_DSPMASK - Select which channels will be affected by the
592 * AHIET_DSPECHO - A DSP effects that adds (cross-)echo and delay.
594 * AHIET_CHANNELINFO - Get info about all channels. (V4)
595 * audioctrl - A pointer to an AHIAudioCtrl structure.
598 * AHIET_MASTERVOLUME - Effect is a struct AHIEffMasterVolume, with
599 * ahiemv_Volume set to the desired volume. The range is 0 to
600 * (channels/hardware channel). Assume you have 4 channels in
601 * mono mode. The range is then 0.0 to 4.0. The range is the same
602 * if the mode is stereo with panning. However, assume you have 4
603 * channels with a stereo mode *without* panning. Then you have two
604 * channels to the left and two to the right => range is 0.0 - 2.0.
605 * Setting the volume outside the range will give an unpredictable
608 * AHIET_OUTPUTBUFFER - Effect is a struct AHIEffOutputBuffer, with
609 * ahieob_Func pointing to a hook that will be called with the
610 * following parameters:
611 * A0 - (struct Hook *)
612 * A2 - (struct AHIAudioCtrl *)
613 * A1 - (struct AHIEffOutputBuffer *)
614 * The information you are looking for then is in ahieob_Type,
615 * ahieob_Buffer and ahieob_Length. Always check ahieob_Type!
616 * ahieob_Length is neither in bytes nor samples, but sample frames.
618 * AHIET_DSPMASK - Effect is a struct AHIEffDSPMask, where ahiedm_Mask
619 * is an array with ahiedm_Channels elements. Each UBYTE in the
620 * array can either make the channel 'wet' (affected by the DSP
621 * effects), by using the AHIEDM_WET constant or 'dry' (not
622 * affected by the DSP effects) by using the AHIEDM_DRY constant.
623 * The default is all channels wet. If ahiedm_Channels does not
624 * equal the current number of channels allocated, the result of
625 * this call is undefined (crash warning!). (V4)
627 * AHIET_DSPECHO - Effect is a struct AHIEffDSPEcho.
628 * ahiede_Delay is the delay in samples (and thus depends on the
631 * ahiede_Feedback is a Fixed value between 0 and 1.0, and defines
632 * how much of the delayed signal should be feed back to the delay
633 * stage. Setting this to 0 gives a delay effect, otherwise echo.
635 * ahiede_Mix tells how much of the delayed signal should be mixed
636 * with the normal signal. Setting this to 0 disables delay/echo,
637 * and setting it to 1.0 outputs only the delay/echo signal.
639 * ahiede_Cross only has effect of the current playback mode is
640 * stereo. It tells how the delayed signal should be panned to
641 * the other channel. 0 means no cross echo, 1.0 means full
644 * If the user has enabled "Fast Echo", AHI may take several short-
645 * cuts to increase the performance. This could include rounding the
646 * parameters to a power of two, or even to the extremes.
648 * If you set ahiede_Mix to 0x10000 and ahiede_Cross to 0x0, much
649 * faster mixing routines will be used, and "Fast Echo" will improve
652 * Otherwise, even with "Fast Echo" turned on, this effect will
653 * probably suck some major CPU cycles on most sound hardware. (V4)
655 * AHIET_CHANNELINFO - Effect is a struct AHIEffChannelInfo, where
656 * ahieci_Func is pointing to a hook that will be called with the
657 * following parameters:
658 * A0 - (struct Hook *)
659 * A2 - (struct AHIAudioCtrl *)
660 * A1 - (struct AHIEffChannelInfo *)
661 * ahieci_Channels must equal the current number of channels used.
662 * ahieci_Offset is an array of ULONGs, which will be filled by
663 * AHI before the hook is called (the offset is specified in sample
664 * frames). The array must have at least ahieci_Channels elements.
666 * This "effect" can be used to find out how far each channel has
667 * played. You must probably keep track of the other parameters
668 * yourself (like which sound is playing, it's volume, balance and
669 * frequency etc) in order have meaningful usage of the information.
673 * NOTE! To turn off an effect, call again with ahie_Effect OR:ed
674 * with AHIET_CANCEL. For example, it is NOT correct to disable
675 * the AHIET_MASTERVOLUME effect by setting ahiemv_Volume to 1.0!
677 * It is important that you always turn off effects before you
678 * deallocate the audio hardware. Otherwise memory may be lost.
679 * It is safe to turn off an effect that has never been turned on
680 * in the first place.
682 * Never count on that an effect will be available. For example,
683 * AHIET_OUTPUTBUFFER is impossible to implement with some sound
687 * An error code, defined in <devices/ahi.h>.
692 * Unlike the other functions whose names begin with "AHI_Set", this
693 * function may NOT be called from an interrupt (or AHI Hook).
695 * Previous to V4, this call always returned AHIE_OK.
698 * The idea of updating the source structure instead of allocating
699 * a new one that is passed the hook it pretty flawed. The reason is
700 * that AHI_SetEffect() originally could be called from interrupts,
701 * and memory allocation is not allowed from within interrupts.
704 * AHI_SetFreq(), AHI_SetSound(), AHI_SetVol(), AHI_LoadSound(),
707 ****************************************************************************
713 _AHI_SetEffect( IPTR
* effect
,
714 struct AHIPrivAudioCtrl
* audioctrl
,
715 struct AHIBase
* AHIBase
)
717 struct Library
*AHIsubBase
;
720 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_ALL
)
722 Debug_SetEffect(effect
, audioctrl
);
725 AHIsubBase
= audioctrl
->ahiac_SubLib
;
727 rc
= AHIsub_SetEffect(effect
, &audioctrl
->ac
);
729 if(audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
730 || rc
!= AHIS_UNKNOWN
)
732 return rc
; /* We're done! */
743 case AHIET_MASTERVOLUME
:
745 struct AHIEffMasterVolume
*emv
= (struct AHIEffMasterVolume
*) effect
;
747 if(audioctrl
->ahiac_SetMasterVolume
!= emv
->ahiemv_Volume
)
749 audioctrl
->ahiac_SetMasterVolume
= emv
->ahiemv_Volume
;
750 rc
= update_MasterVolume( audioctrl
);
755 case AHIET_MASTERVOLUME
|AHIET_CANCEL
:
757 if(audioctrl
->ahiac_SetMasterVolume
!= 0x10000)
759 audioctrl
->ahiac_SetMasterVolume
= 0x10000;
760 rc
= update_MasterVolume( audioctrl
);
768 case AHIET_OUTPUTBUFFER
:
769 audioctrl
->ahiac_EffOutputBufferStruct
= (struct AHIEffOutputBuffer
*) effect
;
773 case AHIET_OUTPUTBUFFER
|AHIET_CANCEL
:
774 audioctrl
->ahiac_EffOutputBufferStruct
= NULL
;
784 rc
= update_DSPMask( (struct AHIEffDSPMask
*) effect
, audioctrl
);
787 case AHIET_DSPMASK
|AHIET_CANCEL
:
788 clear_DSPMask( audioctrl
);
798 rc
= update_DSPEcho( (struct AHIEffDSPEcho
*) effect
, audioctrl
);
801 case AHIET_DSPECHO
|AHIET_CANCEL
:
802 free_DSPEcho( audioctrl
);
811 case AHIET_CHANNELINFO
:
812 audioctrl
->ahiac_EffChannelInfoStruct
= (struct AHIEffChannelInfo
*) effect
;
816 case AHIET_CHANNELINFO
|AHIET_CANCEL
:
817 audioctrl
->ahiac_EffChannelInfoStruct
= NULL
;
826 /******************************************************************************
827 ** AHI_LoadSound **************************************************************
828 ******************************************************************************/
830 /****** ahi.device/AHI_LoadSound ********************************************
833 * AHI_LoadSound -- prepare a sound for playback
836 * error = AHI_LoadSound( sound, type, info, audioctrl );
839 * ULONG AHI_LoadSound( UWORD, ULONG, APTR, struct AHIAudioCtrl * );
842 * Defines an ID number for the sound and prepares it for playback.
845 * sound - The numeric ID to be used as a reference to this sound.
846 * The ID is a number greater or equal to 0 and less than what you
847 * specified with AHIA_Sounds when you called AHI_AllocAudioA().
848 * type - The type of the sound. Currently four types are supported:
849 * AHIST_SAMPLE - array of 8 or 16 bit samples. Note that the
850 * portion of memory where the sample is stored must NOT be
851 * altered until AHI_UnloadSound() has been called! This is
852 * because some audio drivers may wish to upload the samples
853 * to local RAM. It is OK to read, though.
855 * AHIST_DYNAMICSAMPLE - array of 8 or 16 bit samples, which can be
856 * updated dynamically. Typically used to play data that is
857 * loaded from disk or calculated realtime.
858 * Avoid using this sound type as much as possible; it will
859 * use much more CPU power than AHIST_SAMPLE on a DMA/DSP
862 * info - Depends on type:
863 * AHIST_SAMPLE - A pointer to a struct AHISampleInfo, filled with:
864 * ahisi_Type - Format of samples (four formats are supported).
865 * AHIST_M8S: Mono, 8 bit signed (BYTEs).
866 * AHIST_S8S: Stereo, 8 bit signed (2×BYTEs) (V4).
867 * AHIST_M16S: Mono, 16 bit signed (WORDs).
868 * AHIST_S16S: Stereo, 16 bit signed (2×WORDs) (V4).
869 * AHIST_M32S: Mono, 32 bit signed (LONGs). (V6)
870 * AHIST_S32S: Stereo, 32 bit signed (2×LONGs) (V6).
871 * AHIST_L7_1: 7.1, 32 bit signed (8×LONGs) (V6).
872 * ahisi_Address - Address to the sample array.
873 * ahisi_Length - The size of the array, in samples.
874 * Don't even think of setting ahisi_Address to 0 and
875 * ahisi_Length to 0xffffffff as you can do with
876 * AHIST_DYNAMICSAMPLE! Very few DMA/DSP cards have 4 GB onboard
879 * AHIST_DYNAMICSAMPLE A pointer to a struct AHISampleInfo, filled
880 * as described above (AHIST_SAMPLE).
881 * If ahisi_Address is 0 and ahisi_Length is 0xffffffff
882 * AHI_SetSound() can take the real address of an 8 bit sample
883 * to be played as offset argument. Unfortunately, this does not
884 * work for 16 bit samples.
886 * audioctrl - A pointer to an AHIAudioCtrl structure.
889 * An error code, defined in <devices/ahi.h>.
894 * There is no need to place a sample array in Chip memory, but it
895 * MUST NOT be swapped out! Allocate your sample memory with the
896 * MEMF_PUBLIC flag set.
899 * AHIST_L7_1 can only be played using 7.1 audio modes -- it will NOT
900 * be downmixed! It can't be played backwards either.
903 * AHI_UnloadSound(), AHI_SetEffect(), AHI_SetFreq(), AHI_SetSound(),
904 * AHI_SetVol(), <devices/ahi.h>
906 ****************************************************************************
911 _AHI_LoadSound( UWORD sound
,
914 struct AHIPrivAudioCtrl
* audioctrl
,
915 struct AHIBase
* AHIBase
)
918 struct Library
*AHIsubBase
;
921 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
923 Debug_LoadSound(sound
, type
, info
, audioctrl
);
926 AHIsubBase
= audioctrl
->ahiac_SubLib
;
928 rc
= AHIsub_LoadSound(sound
, type
, info
, (struct AHIAudioCtrlDrv
*) audioctrl
);
930 if((audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
) || (rc
!= AHIS_UNKNOWN
))
939 case AHIST_DYNAMICSAMPLE
:
942 struct AHISampleInfo
*si
= (struct AHISampleInfo
*) info
;
944 switch(si
->ahisi_Type
)
947 if( (audioctrl
->ac
.ahiac_Flags
& AHIACF_HIFI
) == 0 )
949 rc
= AHIE_BADSAMPLETYPE
;
963 /* AHI_FreeAudio() will deallocate... */
965 audioctrl
->ahiac_SoundDatas
[sound
].sd_Type
= si
->ahisi_Type
;
966 audioctrl
->ahiac_SoundDatas
[sound
].sd_Addr
= si
->ahisi_Address
;
967 audioctrl
->ahiac_SoundDatas
[sound
].sd_Length
= si
->ahisi_Length
;
971 rc
= AHIE_BADSAMPLETYPE
;
979 rc
= AHIE_BADSOUNDTYPE
;
983 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
985 KPrintF("=>%ld\n", rc
);
991 /******************************************************************************
992 ** AHI_UnloadSound ************************************************************
993 ******************************************************************************/
995 /****** ahi.device/AHI_UnloadSound *****************************************
998 * AHI_UnloadSound -- discard a sound
1001 * AHI_UnloadSound( sound, audioctrl );
1004 * void AHI_UnloadSound( UWORD, struct AHIAudioCtrl * );
1007 * Tells 'ahi.device' that this sound will not be used anymore.
1010 * sound - The ID of the sound to unload.
1011 * audioctrl - A pointer to an AHIAudioCtrl structure.
1018 * This call will not break a Forbid() state.
1025 ****************************************************************************
1030 _AHI_UnloadSound( UWORD sound
,
1031 struct AHIPrivAudioCtrl
* audioctrl
,
1032 struct AHIBase
* AHIBase
)
1034 struct Library
*AHIsubBase
;
1037 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1039 Debug_UnloadSound(sound
, audioctrl
);
1042 AHIsubBase
= audioctrl
->ahiac_SubLib
;
1044 rc
= AHIsub_UnloadSound(sound
, (struct AHIAudioCtrlDrv
*) audioctrl
);
1046 if((audioctrl
->ac
.ahiac_Flags
& AHIACF_NOMIXING
) || (rc
!= AHIS_UNKNOWN
))
1051 audioctrl
->ahiac_SoundDatas
[sound
].sd_Type
= AHIST_NOTYPE
;
1057 /******************************************************************************
1058 ** AHI_PlayA ******************************************************************
1059 ******************************************************************************/
1061 /****** ahi.device/AHI_PlayA ************************************************
1064 * AHI_PlayA -- Start multiple sounds in one call (V4)
1065 * AHI_Play -- varargs stub for AHI_PlayA()
1068 * AHI_PlayA( audioctrl, tags );
1071 * void AHI_PlayA( struct AHIAudioCtrl *, struct TagItem * );
1073 * AHI_Play( AudioCtrl, tag1, ...);
1075 * void AHI_Play( struct AHIAudioCtrl *, Tag, ... );
1078 * This function performs the same actions as multiple calls to
1079 * AHI_SetFreq(), AHI_SetSound() and AHI_SetVol(). The advantages
1080 * of using only one call is that simple loops can be set without
1081 * using a SoundFunc (see AHI_AllocAudioA(), tag AHIA_SoundFunc) and
1082 * that sounds on different channels can be synchronized even when the
1083 * sounds are not started from a PlayerFunc (see AHI_AllocAudioA(), tag
1084 * AHIA_PlayerFunc). The disadvantage is that this call has more
1085 * overhead than AHI_SetFreq(), AHI_SetSound() and AHI_SetVol(). It is
1086 * therefore recommended that you only use this call if you are not
1087 * calling from a SoundFunc or PlayerFunc.
1089 * The supplied tag list works like a 'program'. This means that
1090 * the order of tags matter.
1093 * audioctrl - A pointer to an AHIAudioCtrl structure.
1094 * tags - A pointer to a tag list.
1097 * AHIP_BeginChannel (UWORD) - Before you start setting attributes
1098 * for a sound to play, you have to use this tag to chose a
1099 * channel to operate on. If AHIP_BeginChannel is omitted, the
1100 * result is undefined.
1102 * AHIP_EndChannel (ULONG) - Signals the end of attributes for
1103 * the current channel. If AHIP_EndChannel is omitted, the result
1104 * is undefined. ti_Data MUST BE NULL!
1106 * AHIP_Freq (ULONG) - The playback frequency in Hertz or AHI_MIXFREQ.
1108 * AHIP_Vol (Fixed) - The desired volume. If omitted, but AHIP_Pan is
1109 * present, AHIP_Vol defaults to 0.
1111 * AHIP_Pan (sposition) - The desired panning. If omitted, but AHIP_Vol
1112 * is present, AHIP_Pan defaults to 0 (extreme left).
1114 * AHIP_Sound (UWORD) - Sound to be played, or AHI_NOSOUND.
1116 * AHIP_Offset (ULONG) - Specifies an offset (in samples) into the
1117 * sound. If this tag is present, AHIP_Length MUST be present too!
1119 * AHIP_Length (LONG) - Specifies how many samples that should be
1122 * AHIP_LoopFreq (ULONG)
1123 * AHIP_LoopVol (Fixed)
1124 * AHIP_LoopPan (sposition)
1125 * AHIP_LoopSound (UWORD)
1126 * AHIP_LoopOffset (ULONG)
1127 * AHIP_LoopLength (LONG) - These tags can be used to set simple loop
1128 * attributes. They default to their sisters. These tags must be
1129 * after the other tags.
1140 * AHI_SetFreq(), AHI_SetSound(), AHI_SetVol()
1142 ****************************************************************************
1147 _AHI_PlayA( struct AHIPrivAudioCtrl
* audioctrl
,
1148 struct TagItem
* tags
,
1149 struct AHIBase
* AHIBase
)
1151 struct TagItem
*tag
,*tstate
=tags
;
1152 struct Library
*AHIsubBase
;
1153 BOOL setfreq
= FALSE
, setvol
= FALSE
, setsound
= FALSE
,
1154 loopsetfreq
= FALSE
, loopsetvol
= FALSE
, loopsetsound
= FALSE
;
1156 freq
= 0, vol
= 0, pan
= 0, sound
= 0, offset
= 0, length
= 0;
1157 ULONG loopfreq
= 0, loopvol
= 0, looppan
= 0, loopsound
= 0,
1158 loopoffset
= 0, looplength
= 0;
1160 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_ALL
)
1162 Debug_PlayA(audioctrl
,tags
);
1165 AHIsubBase
= ((struct AHIPrivAudioCtrl
*)audioctrl
)->ahiac_SubLib
;
1167 AHIsub_Disable((struct AHIAudioCtrlDrv
*)audioctrl
);
1169 for( tag
= NextTagItem( &tstate
);
1171 tag
= NextTagItem( &tstate
) )
1175 case AHIP_BeginChannel
:
1176 channel
=tag
->ti_Data
;
1177 setfreq
=setvol
=setsound
=loopsetfreq
=loopsetvol
=loopsetsound
= \
1178 vol
=pan
=offset
=length
=loopvol
=looppan
=loopoffset
=looplength
=0;
1202 offset
=tag
->ti_Data
;
1206 length
=tag
->ti_Data
;
1209 loopfreq
=tag
->ti_Data
;
1213 loopvol
=tag
->ti_Data
;
1217 looppan
=tag
->ti_Data
;
1220 case AHIP_LoopSound
:
1221 loopsound
=tag
->ti_Data
;
1224 case AHIP_LoopOffset
:
1225 loopoffset
=tag
->ti_Data
;
1226 loopsetsound
=TRUE
; // AHIP_LoopSound: doesn't have to be present
1228 case AHIP_LoopLength
:
1229 looplength
=tag
->ti_Data
;
1231 case AHIP_EndChannel
:
1233 AHI_SetFreq( channel
, freq
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_IMM
);
1235 AHI_SetFreq( channel
, loopfreq
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_NONE
);
1237 AHI_SetVol( channel
, vol
, pan
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_IMM
);
1239 AHI_SetVol( channel
, loopvol
, looppan
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_NONE
);
1241 AHI_SetSound( channel
, sound
, offset
, length
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_IMM
);
1243 AHI_SetSound( channel
, loopsound
, loopoffset
, looplength
, (struct AHIAudioCtrl
*) audioctrl
, AHISF_NONE
);
1248 AHIsub_Enable((struct AHIAudioCtrlDrv
*)audioctrl
);
1253 /******************************************************************************
1254 ** AHI_SampleFrameSize ********************************************************
1255 ******************************************************************************/
1257 /****** ahi.device/AHI_SampleFrameSize **************************************
1260 * AHI_SampleFrameSize -- get the size of a sample frame (V4)
1263 * size = AHI_SampleFrameSize( sampletype );
1266 * ULONG AHI_SampleFrameSize( ULONG );
1269 * Returns the size in bytes of a sample frame for a given sample type.
1272 * sampletype - The sample type to examine. See <devices/ahi.h> for
1276 * The number of bytes, or 0 for invalid types.
1283 * This function returned trash for invalid sample types
1289 ****************************************************************************
1293 static const UBYTE type2bytes
[]=
1296 2, // AHIST_M16S (1)
1298 4, // AHIST_S16S (3)
1303 4, // AHIST_M32S (8)
1305 8 // AHIST_S32S (10)
1309 _AHI_SampleFrameSize( ULONG sampletype
,
1310 struct AHIBase
* AHIBase
)
1314 if(sampletype
<= AHIST_S32S
)
1316 result
= type2bytes
[sampletype
];
1318 else if(sampletype
== AHIST_L7_1
)
1323 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
1325 Debug_SampleFrameSize(sampletype
);
1326 KPrintF("=>%ld\n",type2bytes
[sampletype
]);