2 AHI - The AHI preferences program
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <devices/ahi.h>
23 #include <exec/memory.h>
24 #include <intuition/intuition.h>
25 #include <prefs/prefhdr.h>
26 #include <workbench/workbench.h>
28 #include <clib/alib_protos.h>
29 #include <proto/ahi.h>
30 #include <proto/dos.h>
31 #include <proto/exec.h>
32 #include <proto/gadtools.h>
33 #include <proto/icon.h>
34 #include <proto/iffparse.h>
35 #include <proto/utility.h>
44 #include "ahiprefs_Cat.h"
47 static BOOL
AddUnit(struct List
*, int);
48 static void FillUnitName(struct UnitNode
*);
50 struct AHIGlobalPrefs globalprefs
;
53 struct Library
*GadToolsBase
= NULL
;
54 struct GadToolsIFace
*IGadTools
= NULL
;
55 struct LocaleIFace
*ILocale
= NULL
;
56 struct AHIIFace
*IAHI
= NULL
;
59 struct Library
*LocaleBase
= NULL
;
60 struct Library
*AHIBase
= NULL
;
61 static struct MsgPort
*AHImp
= NULL
;
62 static struct AHIRequest
*AHIio
= NULL
;
63 static BYTE AHIDevice
= -1;
66 static char deftoolname
[] = {"AHI"};
68 static UWORD DiskI1Data
[] =
71 0x0000,0x0000,0x0004,0x0000,0x0000,0x0000,0x0001,0x0000,
72 0x0000,0x07ff,0x8000,0x4000,0x0000,0x1800,0x6000,0x1000,
73 0x0000,0x20fc,0x1000,0x0800,0x0000,0x4102,0x0800,0x0c00,
74 0x0000,0x4082,0x0800,0x0c00,0x0000,0x4082,0x0800,0x0c00,
75 0x0000,0x2104,0x0800,0x0c00,0x0000,0x1e18,0x1000,0x0c00,
76 0x0000,0x0060,0x2000,0x0c00,0x0000,0x0080,0xc000,0x0c00,
77 0x0000,0x0103,0x0000,0x0c00,0x0000,0x021c,0x0000,0x0c00,
78 0x0000,0x0108,0x0000,0x0c00,0x0000,0x00f0,0x0000,0x0c00,
79 0x0000,0x0108,0x0000,0x0c00,0x0000,0x0108,0x0000,0x0c00,
80 0x4000,0x00f0,0x0000,0x0c00,0x1000,0x0000,0x0000,0x0c00,
81 0x0400,0x0000,0x0000,0x0c00,0x01ff,0xffff,0xffff,0xfc00,
83 0xffff,0xffff,0xfff8,0x0000,0xd555,0x5555,0x5556,0x0000,
84 0xd555,0x5000,0x5555,0x8000,0xd555,0x47ff,0x9555,0x6000,
85 0xd555,0x5f03,0xe555,0x5000,0xd555,0x3e55,0xf555,0x5000,
86 0xd555,0x3f55,0xf555,0x5000,0xd555,0x3f55,0xf555,0x5000,
87 0xd555,0x5e53,0xf555,0x5000,0xd555,0x4147,0xe555,0x5000,
88 0xd555,0x551f,0xd555,0x5000,0xd555,0x557f,0x1555,0x5000,
89 0xd555,0x54fc,0x5555,0x5000,0xd555,0x55e1,0x5555,0x5000,
90 0xd555,0x54f5,0x5555,0x5000,0xd555,0x5505,0x5555,0x5000,
91 0xd555,0x54f5,0x5555,0x5000,0xd555,0x54f5,0x5555,0x5000,
92 0x3555,0x5505,0x5555,0x5000,0x0d55,0x5555,0x5555,0x5000,
93 0x0355,0x5555,0x5555,0x5000,0x0000,0x0000,0x0000,0x0000
97 static struct Image image1
=
106 static STRPTR toolTypes
[] = {
111 static struct DiskObject projIcon
= {
112 WB_DISKMAGIC
, /* Magic Number */
113 WB_DISKVERSION
, /* Version */
114 { /* Embedded Gadget Structure */
115 NULL
, /* Next Gadget Pointer */
116 97,12,52,23, /* Left,Top,Width,Height */
117 GFLG_GADGIMAGE
|GFLG_GADGHBOX
, /* Flags */
118 GACT_IMMEDIATE
|GACT_RELVERIFY
,/* Activation Flags */
119 GTYP_BOOLGADGET
, /* Gadget Type */
120 (APTR
)&image1
, /* Render Image */
121 NULL
, /* Select Image */
122 NULL
, /* Gadget Text */
123 0, /* Mutual Exclude */
124 NULL
, /* Special Info */
128 WBPROJECT
, /* Icon Type */
129 deftoolname
, /* Default Tool */
130 toolTypes
, /* Tool Type Array */
131 NO_ICON_POSITION
, /* Current X */
132 NO_ICON_POSITION
, /* Current Y */
133 NULL
, /* Drawer Structure */
134 NULL
, /* Tool Window */
135 4096 /* Stack Size */
139 /******************************************************************************
140 **** Endian support code. *****************************************************
141 ******************************************************************************/
143 /* See the header file for macros */
145 #if !defined( WORDS_BIGENDIAN )
148 EndianSwapUWORD( UWORD x
) {
149 return ((((x
) >> 8) & 0x00ffU
) |
150 (((x
) << 8) & 0xff00U
) );
154 EndianSwapULONG( ULONG x
) {
155 return ((((x
) >> 24) & 0x000000ffUL
) |
156 (((x
) >> 8) & 0x0000ff00UL
) |
157 (((x
) << 8) & 0x00ff0000UL
) |
158 (((x
) << 24) & 0xff000000UL
) );
162 EndianSwap( size_t size
, void* data
) {
168 *((UWORD
*) data
) = EndianSwapUWORD( *((UWORD
*) data
) );
172 *((ULONG
*) data
) = EndianSwapULONG( *((ULONG
*) data
) );
178 tmp
= EndianSwapULONG( *((ULONG
*) data
) );
179 *((ULONG
*) data
) = EndianSwapULONG( *((ULONG
*) (data
+ 4)) );
180 *((ULONG
*) (data
+ 4)) = tmp
;
185 Printf( "Unknown size: %ld\n", size
);
191 # define EndianSwap(s, x)
194 #define CopyIfValid( s, f, from, to, size ) \
196 if( (size_t) size > offsetof( s, f ) ) { \
198 EndianSwap( sizeof (to).f, &((to).f) ); \
203 /******************************************************************************
204 **** Call to open ahi.device etc. *********************************************
205 ******************************************************************************/
207 BOOL
Initialize(void) {
208 LocaleBase
= OpenLibrary("locale.library", 38);
211 ILocale
= (struct LocaleIFace
*) GetInterface(LocaleBase
, "main", 1, NULL
);
213 GadToolsBase
= OpenLibrary("gadtools.library", 37);
215 if( GadToolsBase
== NULL
) {
216 Printf((char *) msgTextNoOpen
, (ULONG
) "gadtools.library", 37);
221 IGadTools
= (struct GadToolsIFace
*) GetInterface(GadToolsBase
, "main", 1, NULL
);
224 OpenahiprefsCatalog();
226 AHImp
=CreateMsgPort();
228 if( AHImp
!= NULL
) {
229 AHIio
= (struct AHIRequest
*)CreateIORequest(
230 AHImp
,sizeof(struct AHIRequest
));
232 if( AHIio
!= NULL
) {
233 AHIio
->ahir_Version
= 4;
234 AHIDevice
= OpenDevice(AHINAME
,AHI_NO_UNIT
,(struct IORequest
*)AHIio
,0);
236 AHIBase
= (struct Library
*)AHIio
->ahir_Std
.io_Device
;
238 IAHI
= (struct AHIIFace
*) GetInterface(AHIBase
, "main", 1, NULL
);
245 Printf((char *) msgTextNoOpen
, (ULONG
) "ahi.device", 4);
250 /******************************************************************************
251 **** Call to close ahi.device etc. ********************************************
252 ******************************************************************************/
256 DropInterface((struct Interface
*) IAHI
);
257 DropInterface((struct Interface
*) IGadTools
);
258 CloseLibrary(GadToolsBase
);
262 CloseDevice((struct IORequest
*)AHIio
);
263 DeleteIORequest((struct IORequest
*)AHIio
);
264 DeleteMsgPort(AHImp
);
266 AHIBase
= NULL
; AHImp
= NULL
; AHIio
= NULL
; AHIDevice
= -1;
268 CloseahiprefsCatalog();
270 CloseLibrary(LocaleBase
);
275 /***** Local function to create a Unit structure ****************************/
277 static BOOL
AddUnit(struct List
*list
, int unit
) {
280 u
= AllocVec(sizeof(struct UnitNode
), MEMF_CLEAR
);
286 u
->prefs
.ahiup_Unit
= unit
;
287 u
->prefs
.ahiup_Channels
= 1;
288 u
->prefs
.ahiup_AudioMode
= AHI_BestAudioID(AHIDB_Realtime
, TRUE
, TAG_DONE
);
289 u
->prefs
.ahiup_Frequency
= 44100;
290 u
->prefs
.ahiup_MonitorVolume
= 0x00000;
291 u
->prefs
.ahiup_InputGain
= 0x10000;
292 u
->prefs
.ahiup_OutputVolume
= 0x10000;
293 u
->prefs
.ahiup_Input
= 0;
294 u
->prefs
.ahiup_Output
= 0;
298 u
->node
.ln_Pri
= -unit
;
299 Enqueue(list
, (struct Node
*) u
);
304 /***** Local function to create a Unit name **********************************/
306 static void FillUnitName(struct UnitNode
*u
) {
307 if(u
->prefs
.ahiup_Unit
!= AHI_NO_UNIT
) {
308 sprintf((char *) &u
->name
, msgUnitDevice
, u
->prefs
.ahiup_Unit
);
311 sprintf((char *) &u
->name
, msgUnitMusic
);
313 u
->node
.ln_Name
= (char *) &u
->name
;
316 /******************************************************************************
317 **** Returns a list with all avalable units, fills globalprefs ****************
318 ******************************************************************************/
322 // Call with name == NULL to get defaults
324 struct List
*GetUnits(char *name
) {
326 struct IFFHandle
*iff
;
327 BOOL devnodes
[UNITNODES
] = { FALSE
, FALSE
, FALSE
, FALSE
} ;
328 BOOL lownode
= FALSE
;
331 // Reasonable defaults
332 globalprefs
.ahigp_DebugLevel
= AHI_DEBUG_NONE
;
333 globalprefs
.ahigp_DisableSurround
= FALSE
;
334 globalprefs
.ahigp_DisableEcho
= FALSE
;
335 globalprefs
.ahigp_FastEcho
= FALSE
;
336 globalprefs
.ahigp_MaxCPU
= (90 << 16) / 100;
337 globalprefs
.ahigp_ClipMasterVolume
= FALSE
;
338 globalprefs
.ahigp_Pad
= 0;
339 globalprefs
.ahigp_AntiClickTime
= 0;
340 globalprefs
.ahigp_ScaleMode
= AHI_SCALE_FIXED_0_DB
;
342 list
= AllocVec(sizeof(struct List
), MEMF_CLEAR
);
347 if(name
&& (iff
= AllocIFF())) {
348 iff
->iff_Stream
= (ULONG
) Open(name
, MODE_OLDFILE
);
349 if(iff
->iff_Stream
) {
351 if(!OpenIFF(iff
, IFFF_READ
)) {
352 if(!(PropChunk (iff
, ID_PREF
, ID_AHIG
) ||
353 CollectionChunk(iff
, ID_PREF
, ID_AHIU
) ||
354 StopOnExit (iff
, ID_PREF
, ID_FORM
))) {
355 if(ParseIFF(iff
, IFFPARSE_SCAN
) == IFFERR_EOC
) {
356 struct StoredProperty
*global
= FindProp(iff
, ID_PREF
, ID_AHIG
);
357 struct CollectionItem
*ci
= FindCollection(iff
, ID_PREF
, ID_AHIU
);
361 struct AHIGlobalPrefs
*p
= global
->sp_Data
;
363 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DebugLevel
,
364 *p
, globalprefs
, global
->sp_Size
);
365 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DisableSurround
,
366 *p
, globalprefs
, global
->sp_Size
);
367 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DisableEcho
,
368 *p
, globalprefs
, global
->sp_Size
);
369 CopyIfValid( struct AHIGlobalPrefs
, ahigp_FastEcho
,
370 *p
, globalprefs
, global
->sp_Size
);
371 CopyIfValid( struct AHIGlobalPrefs
, ahigp_MaxCPU
,
372 *p
, globalprefs
, global
->sp_Size
);
373 CopyIfValid( struct AHIGlobalPrefs
, ahigp_ClipMasterVolume
,
374 *p
, globalprefs
, global
->sp_Size
);
375 CopyIfValid( struct AHIGlobalPrefs
, ahigp_Pad
,
376 *p
, globalprefs
, global
->sp_Size
);
377 CopyIfValid( struct AHIGlobalPrefs
, ahigp_AntiClickTime
,
378 *p
, globalprefs
, global
->sp_Size
);
379 CopyIfValid( struct AHIGlobalPrefs
, ahigp_ScaleMode
,
380 *p
, globalprefs
, global
->sp_Size
);
383 /* Set upsupported options to their defaults */
385 if( AHIBase
->lib_Version
<= 4 )
387 globalprefs
.ahigp_AntiClickTime
= 0;
388 globalprefs
.ahigp_ScaleMode
= AHI_SCALE_FIXED_SAFE
;
391 if( AHIBase
->lib_Version
>= 5 )
393 globalprefs
.ahigp_DisableSurround
= FALSE
;
394 globalprefs
.ahigp_DisableEcho
= FALSE
;
395 globalprefs
.ahigp_FastEcho
= FALSE
;
396 globalprefs
.ahigp_ClipMasterVolume
= TRUE
;
401 struct AHIUnitPrefs
*p
= ci
->ci_Data
;
404 u
= AllocVec(sizeof(struct UnitNode
), MEMF_CLEAR
);
408 u
->prefs
.ahiup_Unit
= ci_cnt
;
409 u
->prefs
.ahiup_Channels
= 1;
410 u
->prefs
.ahiup_AudioMode
= AHI_DEFAULT_ID
;
411 u
->prefs
.ahiup_Frequency
= AHI_DEFAULT_FREQ
;
412 u
->prefs
.ahiup_MonitorVolume
= 0;
413 u
->prefs
.ahiup_InputGain
= 0;
414 u
->prefs
.ahiup_OutputVolume
= 0x10000;
415 u
->prefs
.ahiup_Input
= 0;
416 u
->prefs
.ahiup_Output
= 0;
420 CopyIfValid( struct AHIUnitPrefs
, ahiup_Unit
,
421 *p
, u
->prefs
, ci
->ci_Size
);
422 CopyIfValid( struct AHIUnitPrefs
, ahiup_Channels
,
423 *p
, u
->prefs
, ci
->ci_Size
);
424 CopyIfValid( struct AHIUnitPrefs
, ahiup_AudioMode
,
425 *p
, u
->prefs
, ci
->ci_Size
);
426 CopyIfValid( struct AHIUnitPrefs
, ahiup_Frequency
,
427 *p
, u
->prefs
, ci
->ci_Size
);
428 CopyIfValid( struct AHIUnitPrefs
, ahiup_MonitorVolume
,
429 *p
, u
->prefs
, ci
->ci_Size
);
430 CopyIfValid( struct AHIUnitPrefs
, ahiup_InputGain
,
431 *p
, u
->prefs
, ci
->ci_Size
);
432 CopyIfValid( struct AHIUnitPrefs
, ahiup_OutputVolume
,
433 *p
, u
->prefs
, ci
->ci_Size
);
434 CopyIfValid( struct AHIUnitPrefs
, ahiup_Input
,
435 *p
, u
->prefs
, ci
->ci_Size
);
436 CopyIfValid( struct AHIUnitPrefs
, ahiup_Output
,
437 *p
, u
->prefs
, ci
->ci_Size
);
441 u
->node
.ln_Pri
= -(u
->prefs
.ahiup_Unit
);
442 Enqueue(list
, (struct Node
*) u
);
444 if(u
->prefs
.ahiup_Unit
== AHI_NO_UNIT
) {
447 else if(u
->prefs
.ahiup_Unit
< UNITNODES
) {
448 devnodes
[u
->prefs
.ahiup_Unit
] = TRUE
;
457 Close((BPTR
) iff
->iff_Stream
);
463 // Fill up to lowlevel + UNITNODES device nodes, if not found in prefs file
465 if(!lownode
) AddUnit(list
, AHI_NO_UNIT
);
466 for(i
= 0; i
< UNITNODES
; i
++) {
467 if(!devnodes
[i
]) AddUnit(list
, i
);
475 /******************************************************************************
476 **** Returns a list with all available modes **********************************
477 ******************************************************************************/
479 struct List
*GetModes(struct AHIUnitPrefs
*prefs
) {
482 list
= AllocVec(sizeof(struct List
), MEMF_CLEAR
);
485 ULONG id
= AHI_NextAudioID(AHI_INVALID_ID
);
489 while(id
!= AHI_INVALID_ID
) {
493 t
= AllocVec( sizeof(struct ModeNode
), MEMF_CLEAR
);
498 t
->node
.ln_Name
= t
->name
;
503 AHI_GetAudioAttrs(id
, NULL
,
505 AHIDB_Name
, (ULONG
) t
->node
.ln_Name
,
506 AHIDB_Realtime
, (ULONG
) &realtime
,
509 if((prefs
->ahiup_Unit
== AHI_NO_UNIT
) ||
510 (realtime
&& (id
& 0x00ff0000) != 0x00030000 /* Argh!! */)) {
511 // Insert node alphabetically
512 for(node
= list
->lh_Head
;
514 node
= node
->ln_Succ
) {
515 if(Stricmp(t
->node
.ln_Name
,node
->ln_Name
) < 0)
518 Insert(list
, (struct Node
*) t
, node
->ln_Pred
);
524 id
= AHI_NextAudioID(id
);
530 /******************************************************************************
531 **** Creates a char* array from a list ****************************************
532 ******************************************************************************/
534 char **List2Array(struct List
*list
) {
535 char **strings
, **rstrings
;
539 for(n
= list
->lh_Head
, i
= 0; n
->ln_Succ
; n
= n
->ln_Succ
) {
543 strings
= AllocVec(sizeof(char *) * (i
+ 1), MEMF_CLEAR
);
547 for(n
= list
->lh_Head
; n
->ln_Succ
; n
= n
->ln_Succ
) {
548 *strings
++ = n
->ln_Name
;
555 /******************************************************************************
556 **** Returns a char* array with inputs names **********************************
557 ******************************************************************************/
559 char **GetInputs(ULONG id
) {
560 char **strings
, **rstrings
;
564 AHI_GetAudioAttrs(id
, NULL
,
565 AHIDB_Inputs
, (ULONG
) &inputs
,
568 strings
= AllocVec(sizeof(char *) * (inputs
+ 1) + (32 * inputs
), MEMF_CLEAR
);
572 char *string
= (char *) &strings
[inputs
+ 1];
574 for(i
= 0; i
< inputs
; i
++) {
575 if(AHI_GetAudioAttrs(id
, NULL
,
578 AHIDB_Input
, (ULONG
) string
,
589 /******************************************************************************
590 **** Returns a char* array with outputs names *********************************
591 ******************************************************************************/
593 char **GetOutputs(ULONG id
) {
594 char **strings
, **rstrings
;
598 AHI_GetAudioAttrs(id
, NULL
,
599 AHIDB_Outputs
, (ULONG
) &outputs
,
602 strings
= AllocVec(sizeof(char *) * (outputs
+ 1) + (32 * outputs
), MEMF_CLEAR
);
606 char *string
= (char *) &strings
[outputs
+ 1];
608 for(i
= 0; i
< outputs
; i
++) {
609 if(AHI_GetAudioAttrs(id
, NULL
,
612 AHIDB_Output
, (ULONG
) string
,
623 /******************************************************************************
624 **** Saves all units and globalprefs ******************************************
625 ******************************************************************************/
627 BOOL
SaveSettings(char *name
, struct List
*list
) {
628 struct IFFHandle
*iff
;
629 struct PrefHeader header
= { 0, 0, 0 };
631 BOOL success
= FALSE
;
633 if(name
&& (iff
= AllocIFF())) {
634 iff
->iff_Stream
= (ULONG
) Open(name
, MODE_NEWFILE
);
635 if(iff
->iff_Stream
) {
637 if(!OpenIFF(iff
, IFFF_WRITE
)) {
638 if(! PushChunk(iff
, ID_PREF
, ID_FORM
, IFFSIZE_UNKNOWN
)) {
643 if(! PushChunk(iff
, ID_PREF
, ID_PRHD
, sizeof header
)) {
644 EndianSwap( sizeof (UBYTE
), &header
.ph_Version
);
645 EndianSwap( sizeof (UBYTE
), &header
.ph_Type
);
646 EndianSwap( sizeof (ULONG
), &header
.ph_Flags
);
647 WriteChunkBytes(iff
, &header
, sizeof header
);
650 else success
= FALSE
;
653 if(! PushChunk(iff
, ID_PREF
, ID_AHIG
, sizeof globalprefs
)) {
654 struct AHIGlobalPrefs p
;
656 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DebugLevel
,
657 globalprefs
, p
, sizeof p
);
658 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DisableSurround
,
659 globalprefs
, p
, sizeof p
);
660 CopyIfValid( struct AHIGlobalPrefs
, ahigp_DisableEcho
,
661 globalprefs
, p
, sizeof p
);
662 CopyIfValid( struct AHIGlobalPrefs
, ahigp_FastEcho
,
663 globalprefs
, p
, sizeof p
);
664 CopyIfValid( struct AHIGlobalPrefs
, ahigp_MaxCPU
,
665 globalprefs
, p
, sizeof p
);
666 CopyIfValid( struct AHIGlobalPrefs
, ahigp_ClipMasterVolume
,
667 globalprefs
, p
, sizeof p
);
668 CopyIfValid( struct AHIGlobalPrefs
, ahigp_Pad
,
669 globalprefs
, p
, sizeof p
);
670 CopyIfValid( struct AHIGlobalPrefs
, ahigp_AntiClickTime
,
671 globalprefs
, p
, sizeof p
);
672 CopyIfValid( struct AHIGlobalPrefs
, ahigp_ScaleMode
,
673 globalprefs
, p
, sizeof p
);
676 WriteChunkBytes(iff
, &p
, sizeof p
);
679 else success
= FALSE
;
683 for(n
= list
->lh_Head
; n
->ln_Succ
; n
= n
->ln_Succ
) {
684 if(! PushChunk(iff
, ID_PREF
, ID_AHIU
, sizeof(struct AHIUnitPrefs
))) {
685 struct AHIUnitPrefs p
;
687 CopyIfValid( struct AHIUnitPrefs
, ahiup_Unit
,
688 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
689 CopyIfValid( struct AHIUnitPrefs
, ahiup_Channels
,
690 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
691 CopyIfValid( struct AHIUnitPrefs
, ahiup_AudioMode
,
692 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
693 CopyIfValid( struct AHIUnitPrefs
, ahiup_Frequency
,
694 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
695 CopyIfValid( struct AHIUnitPrefs
, ahiup_MonitorVolume
,
696 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
697 CopyIfValid( struct AHIUnitPrefs
, ahiup_InputGain
,
698 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
699 CopyIfValid( struct AHIUnitPrefs
, ahiup_OutputVolume
,
700 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
701 CopyIfValid( struct AHIUnitPrefs
, ahiup_Input
,
702 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
703 CopyIfValid( struct AHIUnitPrefs
, ahiup_Output
,
704 ((struct UnitNode
*) n
)->prefs
, p
, sizeof p
);
706 WriteChunkBytes(iff
, &p
, sizeof p
);
709 else success
= FALSE
;
715 Close((BPTR
) iff
->iff_Stream
);
723 /******************************************************************************
724 **** Write a project icon to disk *********************************************
725 ******************************************************************************/
727 BOOL
WriteIcon(char *name
) {
728 struct DiskObject
*dobj
;
730 STRPTR
* oldtooltypes
;
731 BOOL success
= FALSE
;
733 /* Use the already present icon */
735 dobj
=GetDiskObject(name
);
738 oldtooltypes
= dobj
->do_ToolTypes
;
739 olddeftool
= dobj
->do_DefaultTool
;
741 dobj
->do_ToolTypes
= toolTypes
;
742 dobj
->do_DefaultTool
= deftoolname
;
744 success
= PutDiskObject(name
,dobj
);
746 /* we must restore the original pointers before freeing */
747 dobj
->do_ToolTypes
= oldtooltypes
;
748 dobj
->do_DefaultTool
= olddeftool
;
749 FreeDiskObject(dobj
);
752 /* Try the user's default prefs icon */
753 if((! success
) && (dobj
=GetDiskObject("ENV:Sys/def_Pref"))) {
754 oldtooltypes
= dobj
->do_ToolTypes
;
755 olddeftool
= dobj
->do_DefaultTool
;
757 dobj
->do_ToolTypes
= toolTypes
;
758 dobj
->do_DefaultTool
= deftoolname
;
760 success
= PutDiskObject(name
,dobj
);
762 /* we must restore the original pointers before freeing */
763 dobj
->do_ToolTypes
= oldtooltypes
;
764 dobj
->do_DefaultTool
= olddeftool
;
765 FreeDiskObject(dobj
);
768 /* Else, put our default icon */
770 success
= PutDiskObject(name
,&projIcon
);
777 /******************************************************************************
778 **** Frees a list and all nodes ***********************************************
779 ******************************************************************************/
781 void FreeList(struct List
*list
) {
787 for( n
= RemHead(list
);
797 /******************************************************************************
798 **** Returns the index:th node in a list *************************************
799 ******************************************************************************/
801 struct Node
*GetNode(int index
, struct List
*list
) {
804 if(list
== NULL
|| list
->lh_Head
->ln_Succ
== NULL
)
807 for(n
= list
->lh_Head
; n
->ln_Succ
; n
= n
->ln_Succ
) {
816 /******************************************************************************
817 **** Plays a test sound using the current selected mode and settings **********
818 ******************************************************************************/
820 BOOL
PlaySound( struct AHIUnitPrefs
* prefs
)
822 struct AHIAudioCtrl
* actrl
;
825 actrl
= AHI_AllocAudio( AHIA_AudioID
, prefs
->ahiup_AudioMode
,
826 AHIA_MixFreq
, prefs
->ahiup_Frequency
,
834 int length
= 48000/440;
835 struct AHISampleInfo sound
;
837 sample
= AllocVec( length
* sizeof( *sample
), MEMF_PUBLIC
);
843 for( i
= 0; i
< length
; ++i
)
845 sample
[ i
] = 0x7fff * sin( i
* 2 * M_PI
/ length
);
848 sound
.ahisi_Type
= AHIST_M16S
;
849 sound
.ahisi_Address
= sample
;
850 sound
.ahisi_Length
= length
;
852 if( AHI_LoadSound( 0, AHIST_SAMPLE
, &sound
, actrl
) == AHIE_OK
)
854 if( AHI_ControlAudio( actrl
, AHIC_Play
, FALSE
,
855 AHIC_MonitorVolume
, prefs
->ahiup_MonitorVolume
,
856 AHIC_InputGain
, prefs
->ahiup_InputGain
,
857 AHIC_OutputVolume
, prefs
->ahiup_OutputVolume
,
858 AHIC_Input
, prefs
->ahiup_Input
,
859 AHIC_Output
, prefs
->ahiup_Output
,
860 TAG_DONE
) == AHIE_OK
)
862 ULONG volume
= 0x10000;
864 switch( globalprefs
.ahigp_ScaleMode
)
866 case AHI_SCALE_DYNAMIC_SAFE
:
870 case AHI_SCALE_FIXED_SAFE
:
871 if( prefs
->ahiup_Channels
!= 0 )
873 volume
= 0x10000 / prefs
->ahiup_Channels
;
877 case AHI_SCALE_FIXED_0_DB
:
881 case AHI_SCALE_FIXED_3_DB
:
885 case AHI_SCALE_FIXED_6_DB
:
890 AHI_Play( actrl
, AHIP_BeginChannel
, 0,
898 if( AHI_ControlAudio( actrl
, AHIC_Play
, TRUE
, TAG_DONE
) == AHIE_OK
)
900 if( globalprefs
.ahigp_ScaleMode
== AHI_SCALE_DYNAMIC_SAFE
)
903 AHI_SetVol( 0, volume
/ 2, 0x8000, actrl
, AHISF_IMM
);
905 AHI_SetVol( 0, volume
, 0x8000, actrl
, AHISF_IMM
);
913 AHI_Play( actrl
, AHIP_BeginChannel
, 0,
914 AHIP_Sound
, AHI_NOSOUND
,
918 // Give the anti-click code a chance to do it's work ...
921 AHI_ControlAudio( actrl
, AHIC_Play
, FALSE
,
926 AHI_UnloadSound( 0, actrl
);
932 AHI_FreeAudio( actrl
);