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,
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>
30 #define __NOGLOBALIFACE__
31 #include <proto/ahi.h>
33 #undef __NOGLOBALIFACE__
34 #include <proto/ahi_sub.h>
39 #include "audioctrl.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
55 stccpy( char *to
, const char *from
, int n
)
59 if( n
== 0 ) return 0;
61 while( *from
&& i
< n
)
71 /******************************************************************************
72 ** DizzyTestAudioID & TestAudioID *********************************************
73 ******************************************************************************/
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;
82 struct TagItem
*tstate
, *tag
;
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
,
112 while ((tag
= NextTagItem(&tstate
)))
119 // Give two points for this
121 if( ((tag
->ti_Data
)&0xffff0000) == (id
& 0xffff0000) )
129 if(XNOR(tag
->ti_Data
, volume
))
135 if(XNOR(tag
->ti_Data
, stereo
))
140 if(XNOR(tag
->ti_Data
, panning
))
143 case AHIDB_MultiChannel
:
145 if(XNOR(tag
->ti_Data
, multichannel
))
150 if(XNOR(tag
->ti_Data
, hifi
))
155 if(XNOR(tag
->ti_Data
, pingpong
))
160 if(XNOR(tag
->ti_Data
, record
))
165 if(XNOR(tag
->ti_Data
, realtime
))
168 case AHIDB_FullDuplex
:
170 if(XNOR(tag
->ti_Data
, fullduplex
))
178 if(tag
->ti_Data
<= bits
)
181 case AHIDB_MaxChannels
:
183 if(tag
->ti_Data
<= channels
)
186 case AHIDB_MinMixFreq
:
188 if(tag
->ti_Data
>= minmix
)
191 case AHIDB_MaxMixFreq
:
193 if(tag
->ti_Data
<= maxmix
)
201 return (Fixed
) ((hits
<<16)/total
);
203 return (Fixed
) 0x10000;
208 BOOL
TestAudioID(ULONG id
, struct TagItem
*tags
)
210 if(DizzyTestAudioID(id
, tags
) != 0x10000)
217 /******************************************************************************
218 ** AHI_GetAudioAttrsA *********************************************************
219 ******************************************************************************/
221 /****** ahi.device/AHI_GetAudioAttrsA ***************************************
224 * AHI_GetAudioAttrsA -- examine an audio mode via a tag list
225 * AHI_GetAudioAttrs -- varargs stub for AHI_GetAudioAttrsA()
228 * success = AHI_GetAudioAttrsA( ID, [audioctrl], tags );
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, ... );
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
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
253 * tags - A pointer to a tag list.
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
276 * AHIDB_Realtime (ULONG *) - Modes which return TRUE for this fulfills
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
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
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
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.
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
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
400 * TRUE if everything went well.
407 * In versions earlier than 3, the tags that filled a string buffer would
408 * not NULL-terminate the string on buffer overflows.
411 * AHI_NextAudioID(), AHI_BestAudioIDA()
413 ****************************************************************************
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
;
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
))
444 idtag
[0].ti_Data
=((struct AHIPrivAudioCtrl
*)actrl
)->ahiac_AudioID
;
448 idtag
[0].ti_Data
= (id
== AHI_DEFAULT_ID
? AHIBase
->ahib_AudioMode
: id
);
449 audioctrl
=(struct AHIAudioCtrlDrv
*)CreateAudioCtrl(idtag
);
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
)))
460 struct AHIsubIFace
*IAHIsub
;
461 if ((IAHIsub
= (struct AHIsubIFace
*) GetInterface((struct Library
*) AHIsubBase
, "main", 1, NULL
)) != NULL
)
465 while((tag1
=NextTagItem(&tstate
)))
467 ptr
=(ULONG
*)tag1
->ti_Data
;
472 if((tag2
=FindTagItem(tag1
->ti_Tag
,dbtags
)))
473 stccpy((char *)tag1
->ti_Data
,(char *)tag2
->ti_Data
,stringlen
);
476 case AHIDB_FrequencyArg
:
479 case AHIDB_OutputArg
:
483 case AHIDB_Copyright
:
485 case AHIDB_Annotation
:
486 stccpy((char *)tag1
->ti_Data
,(char *)AHIsub_GetAttr(tag1
->ti_Tag
,0, (IPTR
)"",dbtags
,audioctrl
),stringlen
);
488 // Input & Output strings
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
);
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
);
501 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
503 case AHIDB_MaxChannels
:
504 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,128,dbtags
,audioctrl
);
506 case AHIDB_MinMixFreq
:
507 *ptr
=AHIsub_GetAttr(AHIDB_Frequency
,0,0,dbtags
,audioctrl
);
509 case AHIDB_MaxMixFreq
:
510 *ptr
=AHIsub_GetAttr(AHIDB_Frequency
,(AHIsub_GetAttr(AHIDB_Frequencies
,1,0,dbtags
,audioctrl
)-1),0,dbtags
,audioctrl
);
512 case AHIDB_Frequencies
:
513 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,1,dbtags
,audioctrl
);
515 case AHIDB_Frequency
:
516 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,GetTagData(AHIDB_FrequencyArg
,0,tags
),0,dbtags
,audioctrl
);
519 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,GetTagData(AHIDB_IndexArg
,0,tags
),0,dbtags
,audioctrl
);
521 case AHIDB_MaxPlaySamples
:
522 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,audioctrl
->ahiac_MaxBuffSamples
,dbtags
,audioctrl
);
524 case AHIDB_MaxRecordSamples
:
525 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
527 case AHIDB_MinMonitorVolume
:
528 case AHIDB_MaxMonitorVolume
:
529 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0x00000,dbtags
,audioctrl
);
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
);
538 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,0,dbtags
,audioctrl
);
541 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,1,dbtags
,audioctrl
);
543 // Booleans that defaults to FALSE
546 case AHIDB_FullDuplex
:
547 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,FALSE
,dbtags
,audioctrl
);
549 // Booleans that defaults to TRUE
551 *ptr
=AHIsub_GetAttr(tag1
->ti_Tag
,0,
552 audioctrl
->ahiac_BuffType
!= AHIST_L7_1
,
555 // Tags from the database.
557 if((tag2
=FindTagItem(tag1
->ti_Tag
,dbtags
)))
564 DropInterface((struct Interface
*) IAHIsub
);
571 else // no AHIsubBase
574 else // no database taglist
577 else // no valid audioctrl
579 if(id
!= AHI_INVALID_ID
)
580 AHIFreeVec(audioctrl
);
582 CloseLibrary(AHIsubBase
);
583 UnlockDatabase(audiodb
);
585 else // unable to lock database
588 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_HIGH
)
590 KPrintF("=>%s\n", (IPTR
) (rc
? "TRUE" : "FALSE"));
597 /******************************************************************************
598 ** AHI_BestAudioIDA ***********************************************************
599 ******************************************************************************/
601 /****** ahi.device/AHI_BestAudioIDA *****************************************
604 * AHI_BestAudioIDA -- calculate the best ModeID with given parameters
605 * AHI_BestAudioID -- varargs stub for AHI_BestAudioIDA()
608 * ID = AHI_BestAudioIDA( tags );
611 * ULONG AHI_BestAudioIDA( struct TagItem * );
613 * ID = AHI_BestAudioID( tag1, ... );
615 * ULONG AHI_BestAudioID( Tag, ... );
618 * Determines the best AudioID to fit the parameters set in the tag
622 * tags - A pointer to a tag list. Only the tags present matter.
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
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
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:
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
664 * AHIDB_MinMixFreq (ULONG) - Lowest mixing frequency supported must be
667 * AHIDB_MaxMixFreq (ULONG) - Highest mixing frequency must be greater
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
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.
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.
692 * AHI_NextAudioID(), AHI_GetAudioAttrsA()
694 ****************************************************************************
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...
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
))
738 // Check if this id the better than the last one
739 score
= DizzyTestAudioID(id
, dizzytags
);
740 if(score
> bestscore
)
745 else if(score
== bestscore
)
749 bestid
= id
; // Return the highest suitable audio id.
756 bestid
= AHI_INVALID_ID
;
759 if(AHIBase
->ahib_DebugLevel
>= AHI_DEBUG_LOW
)
761 KPrintF("=>0x%08lx\n",bestid
);