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 <exec/alerts.h>
26 #include <utility/utility.h>
27 #include <utility/tagitem.h>
28 #include <proto/exec.h>
29 #include <proto/utility.h>
31 #define __NOGLOBALIFACE__
32 #include <proto/ahi.h>
34 #undef __NOGLOBALIFACE__
35 #include <proto/ahi_sub.h>
40 #include "audioctrl.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
56 stccpy( char *to
, const char *from
, int n
)
60 if( n
== 0 ) return 0;
62 while( *from
&& i
< n
)
72 /******************************************************************************
73 ** DizzyTestAudioID & TestAudioID *********************************************
74 ******************************************************************************/
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;
83 struct TagItem
*tstate
, *tag
;
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
,
113 while ((tag
= NextTagItem(&tstate
)))
120 // Give two points for this
122 if( ((tag
->ti_Data
)&0xffff0000) == (id
& 0xffff0000) )
130 if(XNOR(tag
->ti_Data
, volume
))
136 if(XNOR(tag
->ti_Data
, stereo
))
141 if(XNOR(tag
->ti_Data
, panning
))
144 case AHIDB_MultiChannel
:
146 if(XNOR(tag
->ti_Data
, multichannel
))
151 if(XNOR(tag
->ti_Data
, hifi
))
156 if(XNOR(tag
->ti_Data
, pingpong
))
161 if(XNOR(tag
->ti_Data
, record
))
166 if(XNOR(tag
->ti_Data
, realtime
))
169 case AHIDB_FullDuplex
:
171 if(XNOR(tag
->ti_Data
, fullduplex
))
179 if(tag
->ti_Data
<= bits
)
182 case AHIDB_MaxChannels
:
184 if(tag
->ti_Data
<= channels
)
187 case AHIDB_MinMixFreq
:
189 if(tag
->ti_Data
>= minmix
)
192 case AHIDB_MaxMixFreq
:
194 if(tag
->ti_Data
<= maxmix
)
202 return (Fixed
) ((hits
<<16)/total
);
204 return (Fixed
) 0x10000;
209 BOOL
TestAudioID(IPTR id
, struct TagItem
*tags
)
211 if(DizzyTestAudioID(id
, tags
) != 0x10000)
218 /******************************************************************************
219 ** AHI_GetAudioAttrsA *********************************************************
220 ******************************************************************************/
222 /****** ahi.device/AHI_GetAudioAttrsA ***************************************
225 * AHI_GetAudioAttrsA -- examine an audio mode via a tag list
226 * AHI_GetAudioAttrs -- varargs stub for AHI_GetAudioAttrsA()
229 * success = AHI_GetAudioAttrsA( ID, [audioctrl], tags );
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, ... );
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
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
254 * tags - A pointer to a tag list.
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
277 * AHIDB_Realtime (IPTR *) - Modes which return TRUE for this fulfills
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
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
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
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.
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
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
401 * TRUE if everything went well.
408 * In versions earlier than 3, the tags that filled a string buffer would
409 * not NULL-terminate the string on buffer overflows.
412 * AHI_NextAudioID(), AHI_BestAudioIDA()
414 ****************************************************************************
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
;
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
))
445 idtag
[0].ti_Data
=((struct AHIPrivAudioCtrl
*)actrl
)->ahiac_AudioID
;
449 idtag
[0].ti_Data
= (id
== AHI_DEFAULT_ID
? AHIBase
->ahib_AudioMode
: id
);
450 audioctrl
=(struct AHIAudioCtrlDrv
*)CreateAudioCtrl(idtag
);
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
)))
461 struct AHIsubIFace
*IAHIsub
;
462 if ((IAHIsub
= (struct AHIsubIFace
*) GetInterface((struct Library
*) AHIsubBase
, "main", 1, NULL
)) != NULL
)
466 while((tag1
=NextTagItem(&tstate
)))
468 ptr
=(IPTR
*)tag1
->ti_Data
;
473 if((tag2
=FindTagItem(tag1
->ti_Tag
,dbtags
)))
474 stccpy((char *)tag1
->ti_Data
,(char *)tag2
->ti_Data
,stringlen
);
477 case AHIDB_FrequencyArg
:
480 case AHIDB_OutputArg
:
484 case AHIDB_Copyright
:
486 case AHIDB_Annotation
:
487 stccpy((char *)tag1
->ti_Data
,(char *)AHIsub_GetAttr(tag1
->ti_Tag
,0, (IPTR
)"",dbtags
,audioctrl
),stringlen
);
489 // Input & Output strings
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
);
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
);
502 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
504 case AHIDB_MaxChannels
:
505 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,128,dbtags
,audioctrl
);
507 case AHIDB_MinMixFreq
:
508 *ptr
=AHIsub_GetAttr(AHIDB_Frequency
,0,0,dbtags
,audioctrl
);
510 case AHIDB_MaxMixFreq
:
511 *ptr
=AHIsub_GetAttr(AHIDB_Frequency
,(AHIsub_GetAttr(AHIDB_Frequencies
,1,0,dbtags
,audioctrl
)-1),0,dbtags
,audioctrl
);
513 case AHIDB_Frequencies
:
514 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,1,dbtags
,audioctrl
);
516 case AHIDB_Frequency
:
517 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,GetTagData(AHIDB_FrequencyArg
,0,tags
),0,dbtags
,audioctrl
);
520 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,GetTagData(AHIDB_IndexArg
,0,tags
),0,dbtags
,audioctrl
);
522 case AHIDB_MaxPlaySamples
:
523 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,audioctrl
->ahiac_MaxBuffSamples
,dbtags
,audioctrl
);
525 case AHIDB_MaxRecordSamples
:
526 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
528 case AHIDB_MinMonitorVolume
:
529 case AHIDB_MaxMonitorVolume
:
530 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0x00000,dbtags
,audioctrl
);
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
);
539 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
542 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,1,dbtags
,audioctrl
);
544 // Booleans that defaults to FALSE
547 case AHIDB_FullDuplex
:
548 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,FALSE
,dbtags
,audioctrl
);
550 // Booleans that defaults to TRUE
552 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,
553 audioctrl
->ahiac_BuffType
!= AHIST_L7_1
,
556 // Tags from the database.
558 if((tag2
=FindTagItem(tag1
->ti_Tag
,dbtags
)))
565 DropInterface((struct Interface
*) IAHIsub
);
572 else // no AHIsubBase
575 else // no database taglist
578 else // no valid audioctrl
580 if(id
!= AHI_INVALID_ID
)
581 AHIFreeVec(audioctrl
);
583 CloseLibrary(AHIsubBase
);
584 UnlockDatabase(audiodb
);
586 else // unable to lock database
589 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_HIGH
)
591 KPrintF("=>%s\n", (IPTR
) (rc
? "TRUE" : "FALSE"));
598 /******************************************************************************
599 ** AHI_BestAudioIDA ***********************************************************
600 ******************************************************************************/
602 /****** ahi.device/AHI_BestAudioIDA *****************************************
605 * AHI_BestAudioIDA -- calculate the best ModeID with given parameters
606 * AHI_BestAudioID -- varargs stub for AHI_BestAudioIDA()
609 * ID = AHI_BestAudioIDA( tags );
612 * IPTR AHI_BestAudioIDA( struct TagItem * );
614 * ID = AHI_BestAudioID( tag1, ... );
616 * IPTR AHI_BestAudioID( Tag, ... );
619 * Determines the best AudioID to fit the parameters set in the tag
623 * tags - A pointer to a tag list. Only the tags present matter.
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
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
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:
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
665 * AHIDB_MinMixFreq (ULONG) - Lowest mixing frequency supported must be
668 * AHIDB_MaxMixFreq (ULONG) - Highest mixing frequency must be greater
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
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.
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.
693 * AHI_NextAudioID(), AHI_GetAudioAttrsA()
695 ****************************************************************************
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...
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
))
739 // Check if this id the better than the last one
740 score
= DizzyTestAudioID(id
, dizzytags
);
741 if(score
> bestscore
)
746 else if(score
== bestscore
)
750 bestid
= id
; // Return the highest suitable audio id.
757 bestid
= AHI_INVALID_ID
;
760 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
762 KPrintF("=>0x%08lx\n",bestid
);