revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Device / modeinfo.c
bloba4eeb3eecb509911aa94b4460bda53e8d0490f78
1 /*
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,
19 MA 02139, USA.
22 #include <config.h>
24 #include <exec/memory.h>
25 #include <exec/alerts.h>
26 #include <utility/utility.h>
27 #include <utility/tagitem.h>
28 #include <proto/exec.h>
29 #include <proto/utility.h>
30 #define __NOLIBBASE__
31 #define __NOGLOBALIFACE__
32 #include <proto/ahi.h>
33 #undef __NOLIBBASE__
34 #undef __NOGLOBALIFACE__
35 #include <proto/ahi_sub.h>
37 #include "ahi_def.h"
38 #include "localize.h"
39 #include "modeinfo.h"
40 #include "audioctrl.h"
41 #include "database.h"
42 #include "debug.h"
43 #include "header.h"
44 #include "misc.h"
47 // Boolean comparison macros
49 #define XOR(a,b) ((a && !b) || (!a && b))
50 #define XNOR(a,b) (! XOR(a,b))
53 // NUL-terminating string copy
55 static int
56 stccpy( char *to, const char *from, int n )
58 int i = 1;
60 if( n == 0 ) return 0;
62 while( *from && i < n )
64 *to++ = *from++;
65 i++;
67 *to = '\0';
69 return i;
72 /******************************************************************************
73 ** DizzyTestAudioID & TestAudioID *********************************************
74 ******************************************************************************/
76 // tags may be NULL
78 Fixed DizzyTestAudioID(IPTR id, struct TagItem *tags )
80 IPTR volume=0,stereo=0,panning=0,hifi=0,pingpong=0,record=0,realtime=0,
81 fullduplex=0,bits=0,channels=0,minmix=0,maxmix=0,multichannel=0;
82 ULONG total=0,hits=0;
83 struct TagItem *tstate, *tag;
85 if(tags == NULL)
87 return (Fixed) 0x10000;
90 if(id == AHI_DEFAULT_ID)
92 id = AHIBase->ahib_AudioMode;
95 AHI_GetAudioAttrs( id, NULL,
96 AHIDB_Volume, (IPTR)&volume,
97 AHIDB_Stereo, (IPTR)&stereo,
98 AHIDB_Panning, (IPTR)&panning,
99 AHIDB_MultiChannel, (IPTR)&multichannel,
100 AHIDB_HiFi, (IPTR)&hifi,
101 AHIDB_PingPong, (IPTR)&pingpong,
102 AHIDB_Record, (IPTR)&record,
103 AHIDB_Bits, (IPTR)&bits,
104 AHIDB_MaxChannels, (IPTR)&channels,
105 AHIDB_MinMixFreq, (IPTR)&minmix,
106 AHIDB_MaxMixFreq, (IPTR)&maxmix,
107 AHIDB_Realtime, (IPTR)&realtime,
108 AHIDB_FullDuplex, (IPTR)&fullduplex,
109 TAG_DONE );
111 tstate = tags;
113 while ((tag = NextTagItem(&tstate)))
115 switch (tag->ti_Tag)
117 // Check source mode
119 case AHIDB_AudioID:
120 // Give two points for this
121 total+=2;
122 if( ((tag->ti_Data)&0xffff0000) == (id & 0xffff0000) )
123 hits+=2;
124 break;
126 // Boolean tags
128 case AHIDB_Volume:
129 total++;
130 if(XNOR(tag->ti_Data, volume))
131 hits++;
132 break;
134 case AHIDB_Stereo:
135 total++;
136 if(XNOR(tag->ti_Data, stereo))
137 hits++;
138 break;
139 case AHIDB_Panning:
140 total++;
141 if(XNOR(tag->ti_Data, panning))
142 hits++;
143 break;
144 case AHIDB_MultiChannel:
145 total++;
146 if(XNOR(tag->ti_Data, multichannel))
147 hits++;
148 break;
149 case AHIDB_HiFi:
150 total++;
151 if(XNOR(tag->ti_Data, hifi))
152 hits++;
153 break;
154 case AHIDB_PingPong:
155 total++;
156 if(XNOR(tag->ti_Data, pingpong))
157 hits++;
158 break;
159 case AHIDB_Record:
160 total++;
161 if(XNOR(tag->ti_Data, record))
162 hits++;
163 break;
164 case AHIDB_Realtime:
165 total++;
166 if(XNOR(tag->ti_Data, realtime))
167 hits++;
168 break;
169 case AHIDB_FullDuplex:
170 total++;
171 if(XNOR(tag->ti_Data, fullduplex))
172 hits++;
173 break;
175 // The rest
177 case AHIDB_Bits:
178 total++;
179 if(tag->ti_Data <= bits)
180 hits++;
181 break;
182 case AHIDB_MaxChannels:
183 total++;
184 if(tag->ti_Data <= channels )
185 hits++;
186 break;
187 case AHIDB_MinMixFreq:
188 total++;
189 if(tag->ti_Data >= minmix)
190 hits++;
191 break;
192 case AHIDB_MaxMixFreq:
193 total++;
194 if(tag->ti_Data <= maxmix)
195 hits++;
196 break;
197 } /* switch */
198 } /* while */
201 if(total)
202 return (Fixed) ((hits<<16)/total);
203 else
204 return (Fixed) 0x10000;
207 // tags may be NULL
209 BOOL TestAudioID(IPTR id, struct TagItem *tags )
211 if(DizzyTestAudioID(id, tags) != 0x10000)
212 return FALSE;
213 else
214 return TRUE;
218 /******************************************************************************
219 ** AHI_GetAudioAttrsA *********************************************************
220 ******************************************************************************/
222 /****** ahi.device/AHI_GetAudioAttrsA ***************************************
224 * NAME
225 * AHI_GetAudioAttrsA -- examine an audio mode via a tag list
226 * AHI_GetAudioAttrs -- varargs stub for AHI_GetAudioAttrsA()
228 * SYNOPSIS
229 * success = AHI_GetAudioAttrsA( ID, [audioctrl], tags );
230 * D0 D0 A2 A1
232 * BOOL AHI_GetAudioAttrsA( IPTR, struct AHIAudioCtrl *,
233 * struct TagItem * );
235 * success = AHI_GetAudioAttrs( ID, [audioctrl], attr1, &result1, ...);
237 * BOOL AHI_GetAudioAttrs( IPTR, struct AHIAudioCtrl *, Tag, ... );
239 * FUNCTION
240 * Retrieve information about an audio mode specified by ID or audioctrl
241 * according to the tags in the tag list. For each entry in the tag
242 * list, ti_Tag identifies the attribute, and ti_Data is mostly a
243 * pointer to a LONG (4 bytes) variable where you wish the result to be
244 * stored.
246 * INPUTS
247 * ID - An audio mode identifier, AHI_DEFAULT_ID (V4) or AHI_INVALID_ID.
248 * audioctrl - A pointer to an AHIAudioCtrl structure, only used if
249 * ID equals AHI_INVALID_ID. Set to NULL if not used. If set to
250 * NULL when used, this function returns immediately. Always set
251 * ID to AHI_INVALID_ID and use audioctrl if you have allocated
252 * a valid AHIAudioCtrl structure. Some of the tags return incorrect
253 * values otherwise.
254 * tags - A pointer to a tag list.
256 * TAGS
257 * AHIDB_Volume (IPTR *) - TRUE if this mode supports volume changes.
259 * AHIDB_Stereo (IPTR *) - TRUE if output is in stereo. Unless
260 * AHIDB_Panning (see below) is TRUE, all even channels are played
261 * to the left and all odd to the right.
263 * AHIDB_MultiChannel (IPTR *) - TRUE if output is in 7.1 channels.
265 * AHIDB_Panning (IPTR *) - TRUE if this mode supports stereo panning.
267 * AHIDB_HiFi (IPTR *) - TRUE if no shortcuts, like pre-division, is
268 * used by the mixing routines.
270 * AHIDB_PingPong (IPTR *) - TRUE if this mode can play samples backwards.
272 * AHIDB_Record (IPTR *) - TRUE if this mode can record samples.
274 * AHIDB_FullDuplex (IPTR *) - TRUE if this mode can record and play at
275 * the same time.
277 * AHIDB_Realtime (IPTR *) - Modes which return TRUE for this fulfills
278 * two criteria:
279 * 1) Calls to AHI_SetVol(), AHI_SetFreq() or AHI_SetSound() will be
280 * performed within (about) 10 ms if called from a PlayFunc Hook.
281 * 2) The PlayFunc Hook will be called at the specified frequency.
282 * If you don't use AHI's PlayFunc Hook, you must not use modes that
283 * are not realtime. (Criterium 2 is not that obvious if you consider
284 * a mode that renders the output to disk as a sample.)
286 * AHIDB_Bits (IPTR *) - The number of output bits (8, 12, 14, 16 etc).
288 * AHIDB_MaxChannels (IPTR *) - The maximum number of channels this mode
289 * can handle.
291 * AHIDB_MinMixFreq (IPTR *) - The minimum mixing frequency supported.
293 * AHIDB_MaxMixFreq (IPTR *) - The maximum mixing frequency supported.
295 * AHIDB_Frequencies (IPTR *) - The number of different sample rates
296 * available.
298 * AHIDB_FrequencyArg (IPTR) - Specifies which frequency
299 * AHIDB_Frequency should return (see below). Range is 0 to
300 * AHIDB_Frequencies-1 (including).
301 * NOTE: ti_Data is NOT a pointer, but an IPTR.
303 * AHIDB_Frequency (IPTR *) - Return the frequency associated with the
304 * index number specified with AHIDB_FrequencyArg (see above).
306 * AHIDB_IndexArg (IPTR) - AHIDB_Index will return the index which
307 * gives the closest frequency to AHIDB_IndexArg
308 * NOTE: ti_Data is NOT a pointer, but an IPTR.
310 * AHIDB_Index (IPTR *) - Return the index associated with the frequency
311 * specified with AHIDB_IndexArg (see above).
313 * AHIDB_MaxPlaySamples (IPTR *) - Return the lowest number of sample
314 * frames that must be present in memory when AHIST_DYNAMICSAMPLE
315 * sounds are used. This number must then be scaled by Fs/Fm, where
316 * Fs is the frequency of the sound and Fm is the mixing frequency.
318 * AHIDB_MaxRecordSamples (IPTR *) - Return the number of sample frames
319 * you will receive each time the RecordFunc is called.
321 * AHIDB_BufferLen (IPTR) - Specifies how many characters will be
322 * copied when requesting text attributes. Default is 0, which
323 * means that AHIDB_Driver, AHIDB_Name, AHIDB_Author,
324 * AHIDB_Copyright, AHIDB_Version and AHIDB_Annotation,
325 * AHIDB_Input and AHIDB_Output will do nothing.
327 * AHIDB_Driver (STRPTR) - Name of driver (excluding path and
328 * extension).
329 * NOTE: ti_Data is a pointer to an UBYTE array where the name
330 * will be stored. See AHIDB_BufferLen.
332 * AHIDB_Name (STRPTR) - Human readable name of this mode.
333 * NOTE: ti_Data is a pointer to an UBYTE array where the name
334 * will be stored. See AHIDB_BufferLen.
336 * AHIDB_Author (STRPTR) - Name of driver author.
337 * NOTE: ti_Data is a pointer to an UBYTE array where the name
338 * will be stored. See AHIDB_BufferLen.
340 * AHIDB_Copyright (STRPTR) - Driver copyright notice.
341 * NOTE: ti_Data is a pointer to an UBYTE array where the name
342 * will be stored. See AHIDB_BufferLen
344 * AHIDB_Version (STRPTR) - Driver version string.
345 * NOTE: ti_Data is a pointer to an UBYTE array where the name
346 * will be stored. See AHIDB_BufferLen.
348 * AHIDB_Annotation (STRPTR) - Annotation by driver author.
349 * NOTE: ti_Data is a pointer to an UBYTE array where the name
350 * will be stored. See AHIDB_BufferLen.
352 * AHIDB_MinMonitorVolume (Fixed *)
353 * AHIDB_MaxMonitorVolume (Fixed *) - Lower/upper limit for input
354 * monitor volume, see AHI_ControlAudioA(). If both are 0.0,
355 * the sound hardware does not have an input monitor feature.
356 * If both are same, but not 0.0, the hardware always sends the
357 * recorded sound to the outputs (at the given volume). (V2)
359 * AHIDB_MinInputGain (Fixed *)
360 * AHIDB_MaxInputGain (Fixed *) - Lower/upper limit for input gain,
361 * see AHI_ControlAudioA(). If both are same, there is no input
362 * gain hardware. (V2)
364 * AHIDB_MinOutputVolume (Fixed *)
365 * AHIDB_MaxOutputVolume (Fixed *) - Lower/upper limit for output
366 * volume, see AHI_ControlAudioA(). If both are same, the sound
367 * card does not have volume control. (V2)
369 * AHIDB_Inputs (IPTR *) - The number of inputs the sound card has.
370 * (V2)
372 * AHIDB_InputArg (IPTR) - Specifies what AHIDB_Input should return
373 * (see below). Range is 0 to AHIDB_Inputs-1 (including).
374 * NOTE: ti_Data is NOT a pointer, but an IPTR. (V2)
376 * AHIDB_Input (STRPTR) - Gives a human readable string describing the
377 * input associated with the index specified with AHIDB_InputArg
378 * (see above). See AHI_ControlAudioA() for how to select one.
379 * NOTE: ti_Data is a pointer to an UBYTE array where the name
380 * will be stored. See AHIDB_BufferLen. (V2)
382 * AHIDB_Outputs (IPTR *) - The number of outputs the sound card
383 * has. (V2)
385 * AHIDB_OutputArg (IPTR) - Specifies what AHIDB_Output should return
386 * (see below). Range is 0 to AHIDB_Outputs-1 (including)
387 * NOTE: ti_Data is NOT a pointer, but an IPTR. (V2)
389 * AHIDB_Output (STRPTR) - Gives a human readable string describing the
390 * output associated with the index specified with AHIDB_OutputArg
391 * (see above). See AHI_ControlAudioA() for how to select one.
392 * NOTE: ti_Data is a pointer to an UBYTE array where the name
393 * will be stored. See AHIDB_BufferLen. (V2)
395 * AHIDB_AudioID (IPTR *) - The ID for this mode. (V4)
397 * If the requested information cannot be found, the variable will be not
398 * be touched.
400 * RESULT
401 * TRUE if everything went well.
403 * EXAMPLE
405 * NOTES
407 * BUGS
408 * In versions earlier than 3, the tags that filled a string buffer would
409 * not NULL-terminate the string on buffer overflows.
411 * SEE ALSO
412 * AHI_NextAudioID(), AHI_BestAudioIDA()
414 ****************************************************************************
418 ULONG
419 _AHI_GetAudioAttrsA( IPTR id,
420 struct AHIPrivAudioCtrl* actrl,
421 struct TagItem* tags,
422 struct AHIBase* AHIBase )
424 struct AHI_AudioDatabase *audiodb;
425 struct TagItem *dbtags,*tag1,*tag2,*tstate=tags;
426 IPTR *ptr;
427 ULONG stringlen;
428 struct Library *AHIsubBase=NULL;
429 struct AHIAudioCtrlDrv *audioctrl=NULL;
430 BOOL rc=TRUE; // TRUE == _everything_ went well
431 struct TagItem idtag[2] = { {AHIA_AudioID, 0} , {TAG_DONE, 0} };
433 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
435 Debug_GetAudioAttrsA(id, actrl, tags);
438 if((audiodb=LockDatabase()))
440 if(id == AHI_INVALID_ID)
442 if(!(audioctrl= (struct AHIAudioCtrlDrv*) actrl))
443 rc=FALSE;
444 else
445 idtag[0].ti_Data=((struct AHIPrivAudioCtrl *)actrl)->ahiac_AudioID;
447 else
449 idtag[0].ti_Data = (id == AHI_DEFAULT_ID ? AHIBase->ahib_AudioMode : id);
450 audioctrl=(struct AHIAudioCtrlDrv *)CreateAudioCtrl(idtag);
453 if(audioctrl && rc )
455 if((dbtags=GetDBTagList(audiodb, idtag[0].ti_Data)))
457 stringlen=GetTagData(AHIDB_BufferLen,0,tags);
458 if((AHIsubBase=OpenLibrary(((struct AHIPrivAudioCtrl *)audioctrl)->ahiac_DriverName,DriverVersion)))
460 #ifdef __AMIGAOS4__
461 struct AHIsubIFace *IAHIsub;
462 if ((IAHIsub = (struct AHIsubIFace *) GetInterface((struct Library *) AHIsubBase, "main", 1, NULL)) != NULL)
464 #endif
466 while((tag1=NextTagItem(&tstate)))
468 ptr=(IPTR *)tag1->ti_Data;
469 switch(tag1->ti_Tag)
471 case AHIDB_Driver:
472 case AHIDB_Name:
473 if((tag2=FindTagItem(tag1->ti_Tag,dbtags)))
474 stccpy((char *)tag1->ti_Data,(char *)tag2->ti_Data,stringlen);
475 break;
476 // Skip these!
477 case AHIDB_FrequencyArg:
478 case AHIDB_IndexArg:
479 case AHIDB_InputArg:
480 case AHIDB_OutputArg:
481 break;
482 // Strings
483 case AHIDB_Author:
484 case AHIDB_Copyright:
485 case AHIDB_Version:
486 case AHIDB_Annotation:
487 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,0, (IPTR)"",dbtags,audioctrl),stringlen);
488 break;
489 // Input & Output strings
490 case AHIDB_Input:
491 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,
492 GetTagData(AHIDB_InputArg,0,tags),
493 (IPTR) GetahiString(msgDefault),dbtags,audioctrl),stringlen);
494 break;
495 case AHIDB_Output:
496 stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,
497 GetTagData(AHIDB_OutputArg,0,tags),
498 (IPTR) GetahiString(msgDefault),dbtags,audioctrl),stringlen);
499 break;
500 // Other
501 case AHIDB_Bits:
502 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
503 break;
504 case AHIDB_MaxChannels:
505 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,128,dbtags,audioctrl);
506 break;
507 case AHIDB_MinMixFreq:
508 *ptr=AHIsub_GetAttr(AHIDB_Frequency,0,0,dbtags,audioctrl);
509 break;
510 case AHIDB_MaxMixFreq:
511 *ptr=AHIsub_GetAttr(AHIDB_Frequency,(AHIsub_GetAttr(AHIDB_Frequencies,1,0,dbtags,audioctrl)-1),0,dbtags,audioctrl);
512 break;
513 case AHIDB_Frequencies:
514 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl);
515 break;
516 case AHIDB_Frequency:
517 *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_FrequencyArg,0,tags),0,dbtags,audioctrl);
518 break;
519 case AHIDB_Index:
520 *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_IndexArg,0,tags),0,dbtags,audioctrl);
521 break;
522 case AHIDB_MaxPlaySamples:
523 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,audioctrl->ahiac_MaxBuffSamples,dbtags,audioctrl);
524 break;
525 case AHIDB_MaxRecordSamples:
526 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
527 break;
528 case AHIDB_MinMonitorVolume:
529 case AHIDB_MaxMonitorVolume:
530 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x00000,dbtags,audioctrl);
531 break;
532 case AHIDB_MinInputGain:
533 case AHIDB_MaxInputGain:
534 case AHIDB_MinOutputVolume:
535 case AHIDB_MaxOutputVolume:
536 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x10000,dbtags,audioctrl);
537 break;
538 case AHIDB_Inputs:
539 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl);
540 break;
541 case AHIDB_Outputs:
542 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl);
543 break;
544 // Booleans that defaults to FALSE
545 case AHIDB_Realtime:
546 case AHIDB_Record:
547 case AHIDB_FullDuplex:
548 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,FALSE,dbtags,audioctrl);
549 break;
550 // Booleans that defaults to TRUE
551 case AHIDB_PingPong:
552 *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,
553 audioctrl->ahiac_BuffType != AHIST_L7_1,
554 dbtags,audioctrl);
555 break;
556 // Tags from the database.
557 default:
558 if((tag2=FindTagItem(tag1->ti_Tag,dbtags)))
559 *ptr=tag2->ti_Data;
560 break;
563 #ifdef __AMIGAOS4__
564 if (IAHIsub) {
565 DropInterface((struct Interface *) IAHIsub);
566 IAHIsub = NULL;
569 #endif
572 else // no AHIsubBase
573 rc=FALSE;
575 else // no database taglist
576 rc=FALSE;
578 else // no valid audioctrl
579 rc=FALSE;
580 if(id != AHI_INVALID_ID)
581 AHIFreeVec(audioctrl);
582 if(AHIsubBase)
583 CloseLibrary(AHIsubBase);
584 UnlockDatabase(audiodb);
586 else // unable to lock database
587 rc=FALSE;
589 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH)
591 KPrintF("=>%s\n", (IPTR) (rc ? "TRUE" : "FALSE"));
594 return (ULONG) rc;
598 /******************************************************************************
599 ** AHI_BestAudioIDA ***********************************************************
600 ******************************************************************************/
602 /****** ahi.device/AHI_BestAudioIDA *****************************************
604 * NAME
605 * AHI_BestAudioIDA -- calculate the best ModeID with given parameters
606 * AHI_BestAudioID -- varargs stub for AHI_BestAudioIDA()
608 * SYNOPSIS
609 * ID = AHI_BestAudioIDA( tags );
610 * D0 A1
612 * IPTR AHI_BestAudioIDA( struct TagItem * );
614 * ID = AHI_BestAudioID( tag1, ... );
616 * IPTR AHI_BestAudioID( Tag, ... );
618 * FUNCTION
619 * Determines the best AudioID to fit the parameters set in the tag
620 * list.
622 * INPUTS
623 * tags - A pointer to a tag list. Only the tags present matter.
625 * TAGS
626 * Many combinations are probably stupid to ask for, like not supporting
627 * panning or recording.
629 * AHIDB_AudioID (IPTR) - The mode must use the same audio hardware
630 * as this mode does.
632 * AHIDB_Volume (BOOL) - If TRUE: mode must support volume changes.
633 * If FALSE: mode must not support volume changes.
635 * AHIDB_Stereo (BOOL) - If TRUE: mode must have stereo output.
636 * If FALSE: mode must not have stereo output (=mono).
638 * AHIDB_MultiChannel (BOOL) - If TRUE: mode must have 7.1 channel output.
639 * If FALSE: mode must not have 7.1 channel output (=mono or stereo).
641 * AHIDB_Panning (BOOL) - If TRUE: mode must support volume panning.
642 * If FALSE: mode must not support volume panning.
644 * AHIDB_HiFi (BOOL) - If TRUE: mode must have HiFi output.
645 * If FALSE: mode must not have HiFi output.
647 * AHIDB_PingPong (BOOL) - If TRUE: mode must support playing samples
648 * backwards. If FALSE: mode must not support playing samples
649 * backwards.
651 * AHIDB_Record (BOOL) - If TRUE: mode must support recording. If FALSE:
652 * mode must not support recording.
654 * AHIDB_Realtime (BOOL) - If TRUE: mode must be realtime. If FALSE:
655 * take a wild guess.
657 * AHIDB_FullDuplex (BOOL) - If TRUE: mode must be able to record and
658 * play at the same time.
660 * AHIDB_Bits (UBYTE) - Mode must have greater or equal number of bits.
662 * AHIDB_MaxChannels (UWORD) - Mode must have greater or equal number
663 * of channels.
665 * AHIDB_MinMixFreq (ULONG) - Lowest mixing frequency supported must be
666 * less or equal.
668 * AHIDB_MaxMixFreq (ULONG) - Highest mixing frequency must be greater
669 * or equal.
671 * AHIB_Dizzy (struct TagItem *) - This tag points to a second tag list.
672 * After all other tags has been tested, the mode that matches these
673 * tags best is returned, i.e. the one that has most of the features
674 * you ask for, and least of the ones you don't want. Without this
675 * second tag list, this function hardly does what its name
676 * suggests. (V4)
678 * RESULT
679 * ID - The best AudioID to use or AHI_INVALID_ID if none of the modes
680 * in the audio database could meet the requirements.
682 * EXAMPLE
684 * NOTES
686 * BUGS
687 * Due to a bug in the code that compared the boolean tag values in
688 * version 4.158 and earlier, TRUE must be equal to 1. The bug is not
689 * present in later revisions.
692 * SEE ALSO
693 * AHI_NextAudioID(), AHI_GetAudioAttrsA()
695 ****************************************************************************
699 IPTR
700 _AHI_BestAudioIDA( struct TagItem* tags,
701 struct AHIBase* AHIBase )
703 IPTR id = AHI_INVALID_ID, bestid = 0;
704 Fixed score, bestscore = 0;
705 struct TagItem *dizzytags;
706 static const struct TagItem const_defdizzy[] =
708 { AHIDB_Volume, TRUE },
709 { AHIDB_Stereo, TRUE },
710 { AHIDB_MultiChannel, FALSE },
711 { AHIDB_Panning, TRUE },
712 { AHIDB_HiFi, TRUE },
713 { AHIDB_Realtime, TRUE },
714 // And we don't care about the rest...
715 { TAG_DONE, 0 }
718 const struct TagItem defdizzy[] =
720 // Give the user's preferred sound card extra points
721 { AHIDB_AudioID, AHIBase->ahib_AudioMode },
722 { TAG_MORE, (IPTR) &const_defdizzy }
725 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW)
727 Debug_BestAudioIDA(tags);
730 dizzytags = (struct TagItem *) GetTagData(AHIB_Dizzy, (IPTR) defdizzy,tags);
732 while(AHI_INVALID_ID != (id=AHI_NextAudioID(id)))
734 if(!TestAudioID(id, tags))
736 continue;
739 // Check if this id the better than the last one
740 score = DizzyTestAudioID(id, dizzytags);
741 if(score > bestscore)
743 bestscore = score;
744 bestid = id;
746 else if(score == bestscore)
748 if(id > bestid)
750 bestid = id; // Return the highest suitable audio id.
755 if(bestid == 0)
757 bestid = AHI_INVALID_ID;
760 if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW)
762 KPrintF("=>0x%08lx\n",bestid);
765 return bestid;