grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / AHI / Device / modeinfo.c
blob3864ce4e596374abcf1edb5a46bbf7bc7c2d13dc
1 /*
2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library 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 GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
18 MA 02139, USA.
21 #include <config.h>
23 #include <exec/memory.h>
24 #include <exec/alerts.h>
25 #include <utility/utility.h>
26 #include <utility/tagitem.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #define __NOLIBBASE__
30 #define __NOGLOBALIFACE__
31 #include <proto/ahi.h>
32 #undef __NOLIBBASE__
33 #undef __NOGLOBALIFACE__
34 #include <proto/ahi_sub.h>
36 #include "ahi_def.h"
37 #include "localize.h"
38 #include "modeinfo.h"
39 #include "audioctrl.h"
40 #include "database.h"
41 #include "debug.h"
42 #include "header.h"
43 #include "misc.h"
46 // Boolean comparison macros
48 #define XOR(a,b) ((a && !b) || (!a && b))
49 #define XNOR(a,b) (! XOR(a,b))
52 // NUL-terminating string copy
54 static int
55 stccpy( char *to, const char *from, int n )
57 int i = 1;
59 if( n == 0 ) return 0;
61 while( *from && i < n )
63 *to++ = *from++;
64 i++;
66 *to = '\0';
68 return i;
71 /******************************************************************************
72 ** DizzyTestAudioID & TestAudioID *********************************************
73 ******************************************************************************/
75 // tags may be NULL
77 Fixed DizzyTestAudioID(ULONG id, struct TagItem *tags )
79 ULONG volume=0,stereo=0,panning=0,hifi=0,pingpong=0,record=0,realtime=0,
80 fullduplex=0,bits=0,channels=0,minmix=0,maxmix=0,multichannel=0;
81 ULONG total=0,hits=0;
82 struct TagItem *tstate, *tag;
84 if(tags == NULL)
86 return (Fixed) 0x10000;
89 if(id == AHI_DEFAULT_ID)
91 id = AHIBase->ahib_AudioMode;
94 AHI_GetAudioAttrs( id, NULL,
95 AHIDB_Volume, (IPTR)&volume,
96 AHIDB_Stereo, (IPTR)&stereo,
97 AHIDB_Panning, (IPTR)&panning,
98 AHIDB_MultiChannel, (IPTR)&multichannel,
99 AHIDB_HiFi, (IPTR)&hifi,
100 AHIDB_PingPong, (IPTR)&pingpong,
101 AHIDB_Record, (IPTR)&record,
102 AHIDB_Bits, (IPTR)&bits,
103 AHIDB_MaxChannels, (IPTR)&channels,
104 AHIDB_MinMixFreq, (IPTR)&minmix,
105 AHIDB_MaxMixFreq, (IPTR)&maxmix,
106 AHIDB_Realtime, (IPTR)&realtime,
107 AHIDB_FullDuplex, (IPTR)&fullduplex,
108 TAG_DONE );
110 tstate = tags;
112 while ((tag = NextTagItem(&tstate)))
114 switch (tag->ti_Tag)
116 // Check source mode
118 case AHIDB_AudioID:
119 // Give two points for this
120 total+=2;
121 if( ((tag->ti_Data)&0xffff0000) == (id & 0xffff0000) )
122 hits+=2;
123 break;
125 // Boolean tags
127 case AHIDB_Volume:
128 total++;
129 if(XNOR(tag->ti_Data, volume))
130 hits++;
131 break;
133 case AHIDB_Stereo:
134 total++;
135 if(XNOR(tag->ti_Data, stereo))
136 hits++;
137 break;
138 case AHIDB_Panning:
139 total++;
140 if(XNOR(tag->ti_Data, panning))
141 hits++;
142 break;
143 case AHIDB_MultiChannel:
144 total++;
145 if(XNOR(tag->ti_Data, multichannel))
146 hits++;
147 break;
148 case AHIDB_HiFi:
149 total++;
150 if(XNOR(tag->ti_Data, hifi))
151 hits++;
152 break;
153 case AHIDB_PingPong:
154 total++;
155 if(XNOR(tag->ti_Data, pingpong))
156 hits++;
157 break;
158 case AHIDB_Record:
159 total++;
160 if(XNOR(tag->ti_Data, record))
161 hits++;
162 break;
163 case AHIDB_Realtime:
164 total++;
165 if(XNOR(tag->ti_Data, realtime))
166 hits++;
167 break;
168 case AHIDB_FullDuplex:
169 total++;
170 if(XNOR(tag->ti_Data, fullduplex))
171 hits++;
172 break;
174 // The rest
176 case AHIDB_Bits:
177 total++;
178 if(tag->ti_Data <= bits)
179 hits++;
180 break;
181 case AHIDB_MaxChannels:
182 total++;
183 if(tag->ti_Data <= channels )
184 hits++;
185 break;
186 case AHIDB_MinMixFreq:
187 total++;
188 if(tag->ti_Data >= minmix)
189 hits++;
190 break;
191 case AHIDB_MaxMixFreq:
192 total++;
193 if(tag->ti_Data <= maxmix)
194 hits++;
195 break;
196 } /* switch */
197 } /* while */
200 if(total)
201 return (Fixed) ((hits<<16)/total);
202 else
203 return (Fixed) 0x10000;
206 // tags may be NULL
208 BOOL TestAudioID(ULONG id, struct TagItem *tags )
210 if(DizzyTestAudioID(id, tags) != 0x10000)
211 return FALSE;
212 else
213 return TRUE;
217 /******************************************************************************
218 ** AHI_GetAudioAttrsA *********************************************************
219 ******************************************************************************/
221 /****** ahi.device/AHI_GetAudioAttrsA ***************************************
223 * NAME
224 * AHI_GetAudioAttrsA -- examine an audio mode via a tag list
225 * AHI_GetAudioAttrs -- varargs stub for AHI_GetAudioAttrsA()
227 * SYNOPSIS
228 * success = AHI_GetAudioAttrsA( ID, [audioctrl], tags );
229 * D0 D0 A2 A1
231 * BOOL AHI_GetAudioAttrsA( ULONG, struct AHIAudioCtrl *,
232 * struct TagItem * );
234 * success = AHI_GetAudioAttrs( ID, [audioctrl], attr1, &result1, ...);
236 * BOOL AHI_GetAudioAttrs( ULONG, struct AHIAudioCtrl *, Tag, ... );
238 * FUNCTION
239 * Retrieve information about an audio mode specified by ID or audioctrl
240 * according to the tags in the tag list. For each entry in the tag
241 * list, ti_Tag identifies the attribute, and ti_Data is mostly a
242 * pointer to a LONG (4 bytes) variable where you wish the result to be
243 * stored.
245 * INPUTS
246 * ID - An audio mode identifier, AHI_DEFAULT_ID (V4) or AHI_INVALID_ID.
247 * audioctrl - A pointer to an AHIAudioCtrl structure, only used if
248 * ID equals AHI_INVALID_ID. Set to NULL if not used. If set to
249 * NULL when used, this function returns immediately. Always set
250 * ID to AHI_INVALID_ID and use audioctrl if you have allocated
251 * a valid AHIAudioCtrl structure. Some of the tags return incorrect
252 * values otherwise.
253 * tags - A pointer to a tag list.
255 * TAGS
256 * AHIDB_Volume (ULONG *) - TRUE if this mode supports volume changes.
258 * AHIDB_Stereo (ULONG *) - TRUE if output is in stereo. Unless
259 * AHIDB_Panning (see below) is TRUE, all even channels are played
260 * to the left and all odd to the right.
262 * AHIDB_MultiChannel (ULONG *) - TRUE if output is in 7.1 channels.
264 * AHIDB_Panning (ULONG *) - TRUE if this mode supports stereo panning.
266 * AHIDB_HiFi (ULONG *) - TRUE if no shortcuts, like pre-division, is
267 * used by the mixing routines.
269 * AHIDB_PingPong (ULONG *) - TRUE if this mode can play samples backwards.
271 * AHIDB_Record (ULONG *) - TRUE if this mode can record samples.
273 * AHIDB_FullDuplex (ULONG *) - TRUE if this mode can record and play at
274 * the same time.
276 * AHIDB_Realtime (ULONG *) - Modes which return TRUE for this fulfills
277 * two criteria:
278 * 1) Calls to AHI_SetVol(), AHI_SetFreq() or AHI_SetSound() will be
279 * performed within (about) 10 ms if called from a PlayFunc Hook.
280 * 2) The PlayFunc Hook will be called at the specified frequency.
281 * If you don't use AHI's PlayFunc Hook, you must not use modes that
282 * are not realtime. (Criterium 2 is not that obvious if you consider
283 * a mode that renders the output to disk as a sample.)
285 * AHIDB_Bits (ULONG *) - The number of output bits (8, 12, 14, 16 etc).
287 * AHIDB_MaxChannels (ULONG *) - The maximum number of channels this mode
288 * can handle.
290 * AHIDB_MinMixFreq (ULONG *) - The minimum mixing frequency supported.
292 * AHIDB_MaxMixFreq (ULONG *) - The maximum mixing frequency supported.
294 * AHIDB_Frequencies (ULONG *) - The number of different sample rates
295 * available.
297 * AHIDB_FrequencyArg (ULONG) - Specifies which frequency
298 * AHIDB_Frequency should return (see below). Range is 0 to
299 * AHIDB_Frequencies-1 (including).
300 * NOTE: ti_Data is NOT a pointer, but an ULONG.
302 * AHIDB_Frequency (ULONG *) - Return the frequency associated with the
303 * index number specified with AHIDB_FrequencyArg (see above).
305 * AHIDB_IndexArg (ULONG) - AHIDB_Index will return the index which
306 * gives the closest frequency to AHIDB_IndexArg
307 * NOTE: ti_Data is NOT a pointer, but an ULONG.
309 * AHIDB_Index (ULONG *) - Return the index associated with the frequency
310 * specified with AHIDB_IndexArg (see above).
312 * AHIDB_MaxPlaySamples (ULONG *) - Return the lowest number of sample
313 * frames that must be present in memory when AHIST_DYNAMICSAMPLE
314 * sounds are used. This number must then be scaled by Fs/Fm, where
315 * Fs is the frequency of the sound and Fm is the mixing frequency.
317 * AHIDB_MaxRecordSamples (ULONG *) - Return the number of sample frames
318 * you will receive each time the RecordFunc is called.
320 * AHIDB_BufferLen (ULONG) - Specifies how many characters will be
321 * copied when requesting text attributes. Default is 0, which
322 * means that AHIDB_Driver, AHIDB_Name, AHIDB_Author,
323 * AHIDB_Copyright, AHIDB_Version and AHIDB_Annotation,
324 * AHIDB_Input and AHIDB_Output will do nothing.
326 * AHIDB_Driver (STRPTR) - Name of driver (excluding path and
327 * extension).
328 * NOTE: ti_Data is a pointer to an UBYTE array where the name
329 * will be stored. See AHIDB_BufferLen.
331 * AHIDB_Name (STRPTR) - Human readable name of this mode.
332 * NOTE: ti_Data is a pointer to an UBYTE array where the name
333 * will be stored. See AHIDB_BufferLen.
335 * AHIDB_Author (STRPTR) - Name of driver author.
336 * NOTE: ti_Data is a pointer to an UBYTE array where the name
337 * will be stored. See AHIDB_BufferLen.
339 * AHIDB_Copyright (STRPTR) - Driver copyright notice.
340 * NOTE: ti_Data is a pointer to an UBYTE array where the name
341 * will be stored. See AHIDB_BufferLen
343 * AHIDB_Version (STRPTR) - Driver version string.
344 * NOTE: ti_Data is a pointer to an UBYTE array where the name
345 * will be stored. See AHIDB_BufferLen.
347 * AHIDB_Annotation (STRPTR) - Annotation by driver author.
348 * NOTE: ti_Data is a pointer to an UBYTE array where the name
349 * will be stored. See AHIDB_BufferLen.
351 * AHIDB_MinMonitorVolume (Fixed *)
352 * AHIDB_MaxMonitorVolume (Fixed *) - Lower/upper limit for input
353 * monitor volume, see AHI_ControlAudioA(). If both are 0.0,
354 * the sound hardware does not have an input monitor feature.
355 * If both are same, but not 0.0, the hardware always sends the
356 * recorded sound to the outputs (at the given volume). (V2)
358 * AHIDB_MinInputGain (Fixed *)
359 * AHIDB_MaxInputGain (Fixed *) - Lower/upper limit for input gain,
360 * see AHI_ControlAudioA(). If both are same, there is no input
361 * gain hardware. (V2)
363 * AHIDB_MinOutputVolume (Fixed *)
364 * AHIDB_MaxOutputVolume (Fixed *) - Lower/upper limit for output
365 * volume, see AHI_ControlAudioA(). If both are same, the sound
366 * card does not have volume control. (V2)
368 * AHIDB_Inputs (ULONG *) - The number of inputs the sound card has.
369 * (V2)
371 * AHIDB_InputArg (ULONG) - Specifies what AHIDB_Input should return
372 * (see below). Range is 0 to AHIDB_Inputs-1 (including).
373 * NOTE: ti_Data is NOT a pointer, but an ULONG. (V2)
375 * AHIDB_Input (STRPTR) - Gives a human readable string describing the
376 * input associated with the index specified with AHIDB_InputArg
377 * (see above). See AHI_ControlAudioA() for how to select one.
378 * NOTE: ti_Data is a pointer to an UBYTE array where the name
379 * will be stored. See AHIDB_BufferLen. (V2)
381 * AHIDB_Outputs (ULONG *) - The number of outputs the sound card
382 * has. (V2)
384 * AHIDB_OutputArg (ULONG) - Specifies what AHIDB_Output should return
385 * (see below). Range is 0 to AHIDB_Outputs-1 (including)
386 * NOTE: ti_Data is NOT a pointer, but an ULONG. (V2)
388 * AHIDB_Output (STRPTR) - Gives a human readable string describing the
389 * output associated with the index specified with AHIDB_OutputArg
390 * (see above). See AHI_ControlAudioA() for how to select one.
391 * NOTE: ti_Data is a pointer to an UBYTE array where the name
392 * will be stored. See AHIDB_BufferLen. (V2)
394 * AHIDB_AudioID (ULONG *) - The ID for this mode. (V4)
396 * If the requested information cannot be found, the variable will be not
397 * be touched.
399 * RESULT
400 * TRUE if everything went well.
402 * EXAMPLE
404 * NOTES
406 * BUGS
407 * In versions earlier than 3, the tags that filled a string buffer would
408 * not NULL-terminate the string on buffer overflows.
410 * SEE ALSO
411 * AHI_NextAudioID(), AHI_BestAudioIDA()
413 ****************************************************************************
417 ULONG
418 _AHI_GetAudioAttrsA( ULONG id,
419 struct AHIPrivAudioCtrl* actrl,
420 struct TagItem* tags,
421 struct AHIBase* AHIBase )
423 struct AHI_AudioDatabase *audiodb;
424 struct TagItem *dbtags,*tag1,*tag2,*tstate=tags;
425 ULONG *ptr;
426 ULONG stringlen;
427 struct Library *AHIsubBase=NULL;
428 struct AHIAudioCtrlDrv *audioctrl=NULL;
429 BOOL rc=TRUE; // TRUE == _everything_ went well
430 struct TagItem idtag[2] = { {AHIA_AudioID, 0} , {TAG_DONE, 0} };
432 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
434 Debug_GetAudioAttrsA(id, actrl, tags);
437 if((audiodb=LockDatabase()))
439 if(id == AHI_INVALID_ID)
441 if(!(audioctrl= (struct AHIAudioCtrlDrv*) actrl))
442 rc=FALSE;
443 else
444 idtag[0].ti_Data=((struct AHIPrivAudioCtrl *)actrl)->ahiac_AudioID;
446 else
448 idtag[0].ti_Data = (id == AHI_DEFAULT_ID ? AHIBase->ahib_AudioMode : id);
449 audioctrl=(struct AHIAudioCtrlDrv *)CreateAudioCtrl(idtag);
452 if(audioctrl && rc )
454 if((dbtags=GetDBTagList(audiodb, idtag[0].ti_Data)))
456 stringlen=GetTagData(AHIDB_BufferLen,0,tags);
457 if((AHIsubBase=OpenLibrary(((struct AHIPrivAudioCtrl *)audioctrl)->ahiac_DriverName,DriverVersion)))
459 #ifdef __AMIGAOS4__
460 struct AHIsubIFace *IAHIsub;
461 if ((IAHIsub = (struct AHIsubIFace *) GetInterface((struct Library *) AHIsubBase, "main", 1, NULL)) != NULL)
463 #endif
465 while((tag1=NextTagItem(&tstate)))
467 ptr=(ULONG *)tag1->ti_Data;
468 switch(tag1->ti_Tag)
470 case AHIDB_Driver:
471 case AHIDB_Name:
472 if((tag2=FindTagItem(tag1->ti_Tag,dbtags)))
473 stccpy((char *)tag1->ti_Data,(char *)tag2->ti_Data,stringlen);
474 break;
475 // Skip these!
476 case AHIDB_FrequencyArg:
477 case AHIDB_IndexArg:
478 case AHIDB_InputArg:
479 case AHIDB_OutputArg:
480 break;
481 // Strings
482 case AHIDB_Author:
483 case AHIDB_Copyright:
484 case AHIDB_Version:
485 case AHIDB_Annotation:
486 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,0, (IPTR)"",dbtags,audioctrl),stringlen);
487 break;
488 // Input & Output strings
489 case AHIDB_Input:
490 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,
491 GetTagData(AHIDB_InputArg,0,tags),
492 (IPTR) GetahiString(msgDefault),dbtags,audioctrl),stringlen);
493 break;
494 case AHIDB_Output:
495 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,
496 GetTagData(AHIDB_OutputArg,0,tags),
497 (IPTR) GetahiString(msgDefault),dbtags,audioctrl),stringlen);
498 break;
499 // Other
500 case AHIDB_Bits:
501 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
502 break;
503 case AHIDB_MaxChannels:
504 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,128,dbtags,audioctrl);
505 break;
506 case AHIDB_MinMixFreq:
507 *ptr=AHIsub_GetAttr(AHIDB_Frequency,0,0,dbtags,audioctrl);
508 break;
509 case AHIDB_MaxMixFreq:
510 *ptr=AHIsub_GetAttr(AHIDB_Frequency,(AHIsub_GetAttr(AHIDB_Frequencies,1,0,dbtags,audioctrl)-1),0,dbtags,audioctrl);
511 break;
512 case AHIDB_Frequencies:
513 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl);
514 break;
515 case AHIDB_Frequency:
516 *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_FrequencyArg,0,tags),0,dbtags,audioctrl);
517 break;
518 case AHIDB_Index:
519 *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_IndexArg,0,tags),0,dbtags,audioctrl);
520 break;
521 case AHIDB_MaxPlaySamples:
522 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,audioctrl->ahiac_MaxBuffSamples,dbtags,audioctrl);
523 break;
524 case AHIDB_MaxRecordSamples:
525 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
526 break;
527 case AHIDB_MinMonitorVolume:
528 case AHIDB_MaxMonitorVolume:
529 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x00000,dbtags,audioctrl);
530 break;
531 case AHIDB_MinInputGain:
532 case AHIDB_MaxInputGain:
533 case AHIDB_MinOutputVolume:
534 case AHIDB_MaxOutputVolume:
535 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x10000,dbtags,audioctrl);
536 break;
537 case AHIDB_Inputs:
538 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
539 break;
540 case AHIDB_Outputs:
541 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl);
542 break;
543 // Booleans that defaults to FALSE
544 case AHIDB_Realtime:
545 case AHIDB_Record:
546 case AHIDB_FullDuplex:
547 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,FALSE,dbtags,audioctrl);
548 break;
549 // Booleans that defaults to TRUE
550 case AHIDB_PingPong:
551 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,
552 audioctrl->ahiac_BuffType != AHIST_L7_1,
553 dbtags,audioctrl);
554 break;
555 // Tags from the database.
556 default:
557 if((tag2=FindTagItem(tag1->ti_Tag,dbtags)))
558 *ptr=tag2->ti_Data;
559 break;
562 #ifdef __AMIGAOS4__
563 if (IAHIsub) {
564 DropInterface((struct Interface *) IAHIsub);
565 IAHIsub = NULL;
568 #endif
571 else // no AHIsubBase
572 rc=FALSE;
574 else // no database taglist
575 rc=FALSE;
577 else // no valid audioctrl
578 rc=FALSE;
579 if(id != AHI_INVALID_ID)
580 AHIFreeVec(audioctrl);
581 if(AHIsubBase)
582 CloseLibrary(AHIsubBase);
583 UnlockDatabase(audiodb);
585 else // unable to lock database
586 rc=FALSE;
588 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
590 KPrintF("=>%s\n", (IPTR) (rc ? "TRUE" : "FALSE"));
593 return (ULONG) rc;
597 /******************************************************************************
598 ** AHI_BestAudioIDA ***********************************************************
599 ******************************************************************************/
601 /****** ahi.device/AHI_BestAudioIDA *****************************************
603 * NAME
604 * AHI_BestAudioIDA -- calculate the best ModeID with given parameters
605 * AHI_BestAudioID -- varargs stub for AHI_BestAudioIDA()
607 * SYNOPSIS
608 * ID = AHI_BestAudioIDA( tags );
609 * D0 A1
611 * ULONG AHI_BestAudioIDA( struct TagItem * );
613 * ID = AHI_BestAudioID( tag1, ... );
615 * ULONG AHI_BestAudioID( Tag, ... );
617 * FUNCTION
618 * Determines the best AudioID to fit the parameters set in the tag
619 * list.
621 * INPUTS
622 * tags - A pointer to a tag list. Only the tags present matter.
624 * TAGS
625 * Many combinations are probably stupid to ask for, like not supporting
626 * panning or recording.
628 * AHIDB_AudioID (ULONG) - The mode must use the same audio hardware
629 * as this mode does.
631 * AHIDB_Volume (BOOL) - If TRUE: mode must support volume changes.
632 * If FALSE: mode must not support volume changes.
634 * AHIDB_Stereo (BOOL) - If TRUE: mode must have stereo output.
635 * If FALSE: mode must not have stereo output (=mono).
637 * AHIDB_MultiChannel (BOOL) - If TRUE: mode must have 7.1 channel output.
638 * If FALSE: mode must not have 7.1 channel output (=mono or stereo).
640 * AHIDB_Panning (BOOL) - If TRUE: mode must support volume panning.
641 * If FALSE: mode must not support volume panning.
643 * AHIDB_HiFi (BOOL) - If TRUE: mode must have HiFi output.
644 * If FALSE: mode must not have HiFi output.
646 * AHIDB_PingPong (BOOL) - If TRUE: mode must support playing samples
647 * backwards. If FALSE: mode must not support playing samples
648 * backwards.
650 * AHIDB_Record (BOOL) - If TRUE: mode must support recording. If FALSE:
651 * mode must not support recording.
653 * AHIDB_Realtime (BOOL) - If TRUE: mode must be realtime. If FALSE:
654 * take a wild guess.
656 * AHIDB_FullDuplex (BOOL) - If TRUE: mode must be able to record and
657 * play at the same time.
659 * AHIDB_Bits (UBYTE) - Mode must have greater or equal number of bits.
661 * AHIDB_MaxChannels (UWORD) - Mode must have greater or equal number
662 * of channels.
664 * AHIDB_MinMixFreq (ULONG) - Lowest mixing frequency supported must be
665 * less or equal.
667 * AHIDB_MaxMixFreq (ULONG) - Highest mixing frequency must be greater
668 * or equal.
670 * AHIB_Dizzy (struct TagItem *) - This tag points to a second tag list.
671 * After all other tags has been tested, the mode that matches these
672 * tags best is returned, i.e. the one that has most of the features
673 * you ask for, and least of the ones you don't want. Without this
674 * second tag list, this function hardly does what its name
675 * suggests. (V4)
677 * RESULT
678 * ID - The best AudioID to use or AHI_INVALID_ID if none of the modes
679 * in the audio database could meet the requirements.
681 * EXAMPLE
683 * NOTES
685 * BUGS
686 * Due to a bug in the code that compared the boolean tag values in
687 * version 4.158 and earlier, TRUE must be equal to 1. The bug is not
688 * present in later revisions.
691 * SEE ALSO
692 * AHI_NextAudioID(), AHI_GetAudioAttrsA()
694 ****************************************************************************
698 ULONG
699 _AHI_BestAudioIDA( struct TagItem* tags,
700 struct AHIBase* AHIBase )
702 ULONG id = AHI_INVALID_ID, bestid = 0;
703 Fixed score, bestscore = 0;
704 struct TagItem *dizzytags;
705 static const struct TagItem const_defdizzy[] =
707 { AHIDB_Volume, TRUE },
708 { AHIDB_Stereo, TRUE },
709 { AHIDB_MultiChannel, FALSE },
710 { AHIDB_Panning, TRUE },
711 { AHIDB_HiFi, TRUE },
712 { AHIDB_Realtime, TRUE },
713 // And we don't care about the rest...
714 { TAG_DONE, 0 }
717 const struct TagItem defdizzy[] =
719 // Give the user's preferred sound card extra points
720 { AHIDB_AudioID, AHIBase->ahib_AudioMode },
721 { TAG_MORE, (IPTR) &const_defdizzy }
724 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW)
726 Debug_BestAudioIDA(tags);
729 dizzytags = (struct TagItem *) GetTagData(AHIB_Dizzy, (IPTR) defdizzy,tags);
731 while(AHI_INVALID_ID != (id=AHI_NextAudioID(id)))
733 if(!TestAudioID(id, tags))
735 continue;
738 // Check if this id the better than the last one
739 score = DizzyTestAudioID(id, dizzytags);
740 if(score > bestscore)
742 bestscore = score;
743 bestid = id;
745 else if(score == bestscore)
747 if(id > bestid)
749 bestid = id; // Return the highest suitable audio id.
754 if(bestid == 0)
756 bestid = AHI_INVALID_ID;
759 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW)
761 KPrintF("=>0x%08lx\n",bestid);
764 return bestid;