BPTR ASMCALL DevClose ( REG(a1, struct AHIRequest *ioreq), REG(a6, struct AHIBase *AHIBase) ) { struct AHIDevUnit *iounit; BPTR seglist=0; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("CloseDevice(0x%08lx)\n", ioreq); } ObtainSemaphore(&AHIBase->ahib_Lock); iounit= (struct AHIDevUnit *) ioreq->ahir_Std.io_Unit; ioreq->ahir_Std.io_Device = (struct Device *) -1; ioreq->ahir_Std.io_Unit = (struct Unit *) -1; if(iounit) { iounit->Unit.unit_OpenCnt--; if(!iounit->Unit.unit_OpenCnt) ExpungeUnit(iounit,AHIBase); } AHIBase->ahib_Library.lib_OpenCnt--; ReleaseSemaphore(&AHIBase->ahib_Lock); if(!AHIBase->ahib_Library.lib_OpenCnt) { if(AHIBase->ahib_Library.lib_Flags & LIBF_DELEXP) seglist=DevExpunge(AHIBase); } return seglist; }
ULONG RemoveAudioMode( ULONG id, struct AHIBase* AHIBase ) { struct AHI_AudioMode *node; struct AHI_AudioDatabase *audiodb; ULONG rc=FALSE; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { Debug_RemoveAudioMode(id); } /* Why ?? */ audiodb = LockDatabaseWrite(); if(audiodb != NULL) { UnlockDatabase(audiodb); } audiodb = LockDatabaseWrite(); if(audiodb != NULL) { if(id != AHI_INVALID_ID) { for(node=(struct AHI_AudioMode *)audiodb->ahidb_AudioModes.mlh_Head; node->ahidbn_MinNode.mln_Succ; node=(struct AHI_AudioMode *)node->ahidbn_MinNode.mln_Succ) { if(id == GetTagData(AHIDB_AudioID, AHI_INVALID_ID, node->ahidbn_Tags)) { Remove((struct Node *) node); FreeVec(node); rc = TRUE; break; } } // Remove the entire database if it's empty Forbid(); if(audiodb->ahidb_AudioModes.mlh_Head->mln_Succ == NULL) { UnlockDatabase(audiodb); audiodb = (struct AHI_AudioDatabase *) FindSemaphore(ADB_NAME); if(audiodb != NULL) { RemSemaphore((struct SignalSemaphore *) audiodb); FreeVec(audiodb); } audiodb = NULL; } Permit(); } UnlockDatabase(audiodb); } if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { KPrintF("=>%ld\n",rc); } return rc; }
ULONG BestAudioIDA( struct TagItem* tags, struct AHIBase* AHIBase ) { ULONG id = AHI_INVALID_ID, bestid = 0; Fixed score, bestscore = 0; struct TagItem *dizzytags; static const struct TagItem defdizzy[] = { // Default is off for performance reasons.. { AHIDB_Volume, FALSE }, { AHIDB_Stereo, FALSE }, { AHIDB_Panning, FALSE }, { AHIDB_HiFi, FALSE }, { AHIDB_PingPong, FALSE }, // Default is on, 'cause they won't hurt performance (?) { AHIDB_Record, TRUE }, { AHIDB_Realtime, TRUE }, { AHIDB_FullDuplex, TRUE }, // And we don't care about the rest... { TAG_DONE, 0 } }; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { Debug_BestAudioIDA(tags); } dizzytags = (struct TagItem *) GetTagData(AHIB_Dizzy, (ULONG) defdizzy,tags); while(AHI_INVALID_ID != (id=AHI_NextAudioID(id))) { if(!TestAudioID(id, tags)) { continue; } // Check if this id the better than the last one score = DizzyTestAudioID(id, dizzytags); if(score > bestscore) { bestscore = score; bestid = id; } else if(score == bestscore) { if(id > bestid) { bestid = id; // Return the highest suitable audio id. } } } if(bestid == 0) { bestid = AHI_INVALID_ID; } if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("=>0x%08lx\n",bestid); } return bestid; }
void Debug_LoadModeFile( STRPTR name) { KPrintF("AHI_LoadModeFile(%s)",name); }
void Debug_AddAudioMode(struct TagItem *tags ) { KPrintF("AHI_AddAudioMode("); PrintTagList(tags); }
void Debug_FreeAudioRequest( struct AHIAudioModeRequester *req ) { KPrintF("AHI_FreeAudioRequest(0x%08lx)\n",req); }
void Debug_AllocAudioRequestA( struct TagItem *tags ) { KPrintF("AHI_AllocAudioRequestA("); PrintTagList(tags); }
void Debug_GetAudioAttrsA( ULONG id, struct AHIAudioCtrlDrv *audioctrl, struct TagItem *tags ) { KPrintF("AHI_GetAudioAttrsA(0x%08lx, 0x%08lx,",id,audioctrl); PrintTagList(tags); }
static void UnlockResource( struct ResourceIterator* iter, struct ResourceContext* ctx ) { if( ! iter->m_HasLock ) { return; } switch( iter->m_Resource->isapnpr_Type ) { case ISAPNP_NT_IRQ_RESOURCE: { #ifdef DEBUG_ITERATORS KPrintF( "U IRQ %ld\n", iter->m_IRQBit ); #endif ctx->m_IRQ[ iter->m_IRQBit ] = NULL; break; } case ISAPNP_NT_DMA_RESOURCE: { #ifdef DEBUG_ITERATORS KPrintF( "U DMA %ld\n", iter->m_ChannelBit ); #endif ctx->m_DMA[ iter->m_ChannelBit ] = NULL; break; } case ISAPNP_NT_IO_RESOURCE: { struct ResourceIteratorRef* io; #ifdef DEBUG_ITERATORS KPrintF( "U IO %lx-%lx\n", iter->m_Base, iter->m_Base + iter->m_Length ); #endif for( io = (struct ResourceIteratorRef*) ctx->m_IO.mlh_Head; io->m_MinNode.mln_Succ != NULL; io = (struct ResourceIteratorRef*) io->m_MinNode.mln_Succ ) { if( io->m_Iterator->m_Base == iter->m_Base ) { Remove( (struct Node*) io ); FreeVec( io ); break; } } break; } case ISAPNP_NT_MEMORY_RESOURCE: default: break; } iter->m_HasLock = FALSE; }
static BOOL LockResource( struct ResourceIterator* iter, struct ResourceContext* ctx ) { struct ResourceIterator* conflict = NULL; switch( iter->m_Resource->isapnpr_Type ) { case ISAPNP_NT_IRQ_RESOURCE: { #ifdef DEBUG_ITERATORS KPrintF( "L IRQ %ld", iter->m_IRQBit ); #endif if( ctx->m_IRQ[ iter->m_IRQBit ] == NULL ) { ctx->m_IRQ[ iter->m_IRQBit ] = iter; } else { conflict = ctx->m_IRQ[ iter->m_IRQBit ]; } break; } case ISAPNP_NT_DMA_RESOURCE: { #ifdef DEBUG_ITERATORS KPrintF( "L DMA %ld", iter->m_ChannelBit ); #endif if( ctx->m_DMA[ iter->m_ChannelBit ] == NULL ) { ctx->m_DMA[ iter->m_ChannelBit ] = iter; } else { conflict = ctx->m_DMA[ iter->m_ChannelBit ]; } break; } case ISAPNP_NT_IO_RESOURCE: { struct ResourceIteratorRef* io; struct ResourceIteratorRef* new_io; struct Node* position = NULL; UWORD base = iter->m_Base; UWORD length = iter->m_Length; #ifdef DEBUG_ITERATORS KPrintF( "L IO %lx-%lx", base, base + length ); #endif for( io = (struct ResourceIteratorRef*) ctx->m_IO.mlh_Head; io->m_MinNode.mln_Succ != NULL; io = (struct ResourceIteratorRef*) io->m_MinNode.mln_Succ ) { UWORD io_base = io->m_Iterator->m_Base; UWORD io_length = io->m_Iterator->m_Length; if( ( base <= io_base && ( base + length ) > io_base ) || ( base >= io_base && base < ( io_base + io_length ) ) ) { // Collision! conflict = io->m_Iterator; break; } if( base + length <= io_base ) { // No more collisions possible; insert before this one position = (struct Node*) io->m_MinNode.mln_Pred; break; } } if( conflict == NULL ) { // Insert the node new_io = AllocVec( sizeof( *new_io ), MEMF_PUBLIC ); if( new_io == NULL ) { return FALSE; } else { new_io->m_Iterator = iter; if( position == NULL ) { AddTail( (struct List*) &ctx->m_IO, (struct Node*) new_io ); } else { Insert( (struct List*) &ctx->m_IO, (struct Node*) new_io, position ); } } } break; } case ISAPNP_NT_MEMORY_RESOURCE: default: break; } if( conflict != NULL ) { conflict->m_InConflict = TRUE; iter->m_HasLock = FALSE; } else { iter->m_HasLock = TRUE; } #ifdef DEBUG_ITERATORS if( iter->m_HasLock ) KPrintF( " OK\n" ); else KPrintF( " failed\n" ); #endif return iter->m_HasLock; }
void __asm __saveds L_Test(void) { KPrintF("test\n"); }
static void Slave( struct ExecBase* SysBase ) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct AROSBase* AROSBase; BOOL running; ULONG signals; int bytes_in_buffer = 0; int offset_in_buffer = 0; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->ahisubbase; AROSBase = (struct AROSBase*) AHIsubBase; dd->slavesignal = AllocSignal( -1 ); if( dd->slavesignal != -1 ) { // Everything set up. Tell Master we're alive and healthy. Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); running = TRUE; // The main playback loop follow while( running ) { signals = SetSignal(0L,0L); // KPrintF("++++ arosdriver_after signal checking\n"); if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) ) { running = FALSE; } else { int skip_mix; int bytes_avail; // First Delay() until there is at least one fragment free while( TRUE ) { int frag_avail, frag_alloc, frag_size; OSS_GetOutputInfo( &frag_avail, &frag_alloc, &frag_size, &bytes_avail ); // KPrintF( "%ld fragments available, %ld alloced (%ld bytes each). %ld bytes total\n", frag_avail, frag_alloc, frag_size, bytes_avail ); if( frag_avail == 0 ) { // This is actually quite a bit too long delay :-( For // comparison, the SB Live/Audigy driver uses 1/1000 s // polling ... // KPrintF("Delay\n"); #if USE_TIMERTICK SmallDelay(SysBase); #else Delay( 1 ); #endif } else { break; } } skip_mix = 0;/*CallHookA( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );*/ while( bytes_avail > 0 ) { // KPrintF( "%ld bytes in current buffer.\n", bytes_in_buffer ); if( bytes_in_buffer == 0 ) { int skip = 0; int offset = 0; int samples = 0; int bytes = 0; int i; WORD* src; WORD* dst; CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL ); samples = AudioCtrl->ahiac_BuffSamples; bytes = samples * 2; // one 16 bit sample is 2 bytes switch( AudioCtrl->ahiac_BuffType ) { case AHIST_M16S: skip = 1; offset = 0; break; case AHIST_M32S: skip = 2; offset = 1; break; case AHIST_S16S: skip = 1; offset = 0; samples *= 2; bytes *= 2; break; case AHIST_S32S: skip = 2; offset = 1; samples *= 2; bytes *= 2; break; } bytes_in_buffer = bytes; offset_in_buffer = 0; if( ! skip_mix ) { CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer ); } src = ((WORD*) dd->mixbuffer) + offset; dst = dd->mixbuffer; for( i = 0; i < samples; ++i ) { *dst++ = *src; src += skip; } // KPrintF( "Mixed %ld/%ld new bytes/samples\n", bytes, samples ); } while( bytes_in_buffer > 0 && bytes_avail > 0 ) { int written; int counter = 0; do { written = OSS_Write( dd->mixbuffer + offset_in_buffer, min( bytes_in_buffer, bytes_avail ) ); if (counter > 10) { if (written < 0) written = 0; break; } if (written < 0) KPrintF("OSS_Write returned %ld. counter %ld bytes_in_buffer %ld bytes_avail %ld\n", written, counter, bytes_in_buffer, bytes_avail); counter++; } while (written < 0); bytes_in_buffer -= written; offset_in_buffer += written; bytes_avail -= written; // KPrintF( "Wrote %ld bytes (%ld bytes in buffer, offset=%ld, %ld bytes available in OSS buffers\n", // written, bytes_in_buffer, offset_in_buffer, bytes_avail ); } } CallHookA( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 ); } } } FreeSignal( dd->slavesignal ); dd->slavesignal = -1; Forbid(); // Tell the Master we're dying Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); dd->slavetask = NULL; // Multitaking will resume when we are dead. }
ULONG _DevOpen ( struct AHIRequest* ioreq, ULONG unit, ULONG flags, struct AHIBase* AHIBase ) { ULONG rc = 0; BOOL error = FALSE; struct AHIDevUnit *iounit=NULL; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("OpenDevice(%ld, 0x%08lx, %ld)", unit, (ULONG) ioreq, flags); } // Check if size includes the ahir_Version field if(ioreq->ahir_Std.io_Message.mn_Length < (sizeof(struct IOStdReq) + 2)) { Req( "Bad parameters to OpenDevice()." ); ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; return IOERR_OPENFAIL; } // One more check... if((unit != AHI_NO_UNIT) && (ioreq->ahir_Version >= 4)) { if(ioreq->ahir_Std.io_Message.mn_Length < sizeof(struct AHIRequest)) { Req( "Bad parameters to OpenDevice()." ); ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; return IOERR_OPENFAIL; } else { /* KPrintF( "Tagging %08lx on task %08lx\n", ioreq, FindTask(0)); */ ioreq->ahir_Private[1] = (ULONG) ioreq; } } AHIBase->ahib_Library.lib_OpenCnt++; ObtainSemaphore(&AHIBase->ahib_Lock); if( ! (flags & AHIDF_NOMODESCAN)) { // Load database if not already loaded if(AHI_NextAudioID(AHI_INVALID_ID) == (ULONG) AHI_INVALID_ID) { AHI_LoadModeFile("DEVS:AudioModes"); // Be quiet here. - Piru if (IS_MORPHOS) { APTR *windowptr = &((struct Process *) FindTask(NULL))->pr_WindowPtr; APTR oldwindowptr = *windowptr; *windowptr = (APTR) -1; AHI_LoadModeFile("MOSSYS:DEVS/AudioModes"); *windowptr = oldwindowptr; } } } if( ioreq->ahir_Version > AHIBase->ahib_Library.lib_Version) error=TRUE; else { if(unit < AHI_UNITS) { iounit=InitUnit(unit,AHIBase); if(!iounit) error=TRUE; } else if(unit == AHI_NO_UNIT) InitUnit(unit,AHIBase); } if(!error) { ioreq->ahir_Std.io_Unit=(struct Unit *) iounit; if(iounit) // Is NULL for AHI_NO_UNIT iounit->Unit.unit_OpenCnt++; AHIBase->ahib_Library.lib_OpenCnt++; AHIBase->ahib_Library.lib_Flags &=~LIBF_DELEXP; } else { rc=IOERR_OPENFAIL; ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; ioreq->ahir_Std.io_Device=(struct Device *) -1; ioreq->ahir_Std.io_Unit=(struct Unit *) -1; } ReleaseSemaphore(&AHIBase->ahib_Lock); AHIBase->ahib_Library.lib_OpenCnt--; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("=>%ld\n",rc); } return rc; }
ULONG LoadModeFile( UBYTE* name, struct AHIBase* AHIBase ) { ULONG rc=FALSE; struct FileInfoBlock *fib; BPTR lock,thisdir; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { Debug_LoadModeFile(name); } SetIoErr(NULL); fib = AllocDosObject(DOS_FIB, TAG_DONE); if(fib != NULL) { lock = Lock(name, ACCESS_READ); if(lock != NULL) { if(Examine(lock,fib)) { if(fib->fib_DirEntryType>0) // Directory? { thisdir = CurrentDir(lock); while(ExNext(lock, fib)) { if(fib->fib_DirEntryType>0) { continue; // AHI_LoadModeFile(fib->fib_FileName); for recursion } else { rc = AddModeFile(fib->fib_FileName); if(!rc) { break; } } } if(IoErr() == ERROR_NO_MORE_ENTRIES) { SetIoErr(NULL); } CurrentDir(thisdir); } else // Plain file { rc = AddModeFile(name); } } UnLock(lock); } FreeDosObject(DOS_FIB,fib); } if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { KPrintF("=>%ld\n",rc); } return rc; }
void Debug_UnloadSound( UWORD sound, struct AHIPrivAudioCtrl *audioctrl ) { KPrintF("AHI_UnloadSound(%ld, 0x%08lx)\n", sound, audioctrl); }
void Debug_FreeAudio( struct AHIPrivAudioCtrl *audioctrl ) { KPrintF("AHI_FreeAudio(0x%08lx)\n",audioctrl); }
void Debug_NextAudioID( ULONG id) { KPrintF("AHI_NextAudioID(0x%08lx)",id); }
void Debug_KillAudio( void ) { KPrintF("AHI_KillAudio()\n"); }
void Debug_BestAudioIDA( struct TagItem *tags ) { KPrintF("AHI_BestAudioIDA("); PrintTagList(tags); }
void Debug_ControlAudioA( struct AHIPrivAudioCtrl *audioctrl, struct TagItem *tags ) { KPrintF("AHI_ControlAudioA(0x%08lx,",audioctrl); PrintTagList(tags); }
void Debug_AudioRequestA( struct AHIAudioModeRequester *req, struct TagItem *tags ) { KPrintF("AHI_AudioRequestA(0x%08lx,",req); PrintTagList(tags); }
void Debug_SetVol( UWORD chan, Fixed vol, sposition pan, struct AHIPrivAudioCtrl *audioctrl, ULONG flags) { KPrintF("AHI_SetVol(%ld, 0x%08lx, 0x%08lx, 0x%08lx, %ld)\n", chan & 0xffff, vol, pan, audioctrl, flags); }
void Debug_SampleFrameSize( ULONG sampletype) { KPrintF("AHI_SampleFrameSize(%ld)",sampletype); }
void Debug_SetFreq( UWORD chan, ULONG freq, struct AHIPrivAudioCtrl *audioctrl, ULONG flags) { KPrintF("AHI_SetFreq(%ld, %ld, 0x%08lx, %ld)\n", chan & 0xffff, freq, audioctrl, flags); }
void Debug_RemoveAudioMode( ULONG id) { KPrintF("AHI_RemoveAudioMode(0x%08lx)",id); }
void Debug_SetSound( UWORD chan, UWORD sound, ULONG offset, LONG length, struct AHIPrivAudioCtrl *audioctrl, ULONG flags) { KPrintF("AHI_SetSound(%ld, %ld, 0x%08lx, 0x%08lx, 0x%08lx, %ld)\n", chan & 0xffff, sound & 0xffff, offset, length, audioctrl, flags); }
ULONG GetAudioAttrsA( ULONG id, struct AHIPrivAudioCtrl* actrl, struct TagItem* tags, struct AHIBase* AHIBase ) { struct AHI_AudioDatabase *audiodb; struct TagItem *dbtags,*tag1,*tag2,*tstate=tags; ULONG *ptr; ULONG stringlen; struct Library *AHIsubBase=NULL; struct AHIAudioCtrlDrv *audioctrl=NULL; BOOL rc=TRUE; // TRUE == _everything_ went well struct TagItem idtag[2] = { {AHIA_AudioID, 0} , {TAG_DONE, 0} }; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { Debug_GetAudioAttrsA(id, actrl, tags); } if((audiodb=LockDatabase())) { if(id == AHI_INVALID_ID) { if(!(audioctrl= (struct AHIAudioCtrlDrv*) actrl)) rc=FALSE; else idtag[0].ti_Data=((struct AHIPrivAudioCtrl *)actrl)->ahiac_AudioID; } else { idtag[0].ti_Data = (id == AHI_DEFAULT_ID ? AHIBase->ahib_AudioMode : id); audioctrl=(struct AHIAudioCtrlDrv *)CreateAudioCtrl(idtag); } if(audioctrl && rc ) { if((dbtags=GetDBTagList(audiodb, idtag[0].ti_Data))) { stringlen=GetTagData(AHIDB_BufferLen,0,tags); if((AHIsubBase=OpenLibrary(((struct AHIPrivAudioCtrl *)audioctrl)->ahiac_DriverName,DriverVersion))) { while((tag1=NextTagItem(&tstate))) { ptr=(ULONG *)tag1->ti_Data; switch(tag1->ti_Tag) { case AHIDB_Driver: case AHIDB_Name: if((tag2=FindTagItem(tag1->ti_Tag,dbtags))) stccpy((char *)tag1->ti_Data,(char *)tag2->ti_Data,stringlen); break; // Skip these! case AHIDB_FrequencyArg: case AHIDB_IndexArg: case AHIDB_InputArg: case AHIDB_OutputArg: break; // Strings case AHIDB_Author: case AHIDB_Copyright: case AHIDB_Version: case AHIDB_Annotation: stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag,0,(ULONG)"",dbtags,audioctrl),stringlen); break; // Input & Output strings case AHIDB_Input: stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag, GetTagData(AHIDB_InputArg,0,tags), (ULONG) GetahiString(msgDefault),dbtags,audioctrl),stringlen); break; case AHIDB_Output: stccpy((char *)tag1->ti_Data,(char *)AHIsub_GetAttr(tag1->ti_Tag, GetTagData(AHIDB_OutputArg,0,tags), (ULONG) GetahiString(msgDefault),dbtags,audioctrl),stringlen); break; // Other case AHIDB_Bits: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl); break; case AHIDB_MaxChannels: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,128,dbtags,audioctrl); break; case AHIDB_MinMixFreq: *ptr=AHIsub_GetAttr(AHIDB_Frequency,0,0,dbtags,audioctrl); break; case AHIDB_MaxMixFreq: *ptr=AHIsub_GetAttr(AHIDB_Frequency,(AHIsub_GetAttr(AHIDB_Frequencies,1,0,dbtags,audioctrl)-1),0,dbtags,audioctrl); break; case AHIDB_Frequencies: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl); break; case AHIDB_Frequency: *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_FrequencyArg,0,tags),0,dbtags,audioctrl); break; case AHIDB_Index: *ptr=AHIsub_GetAttr(tag1->ti_Tag,GetTagData(AHIDB_IndexArg,0,tags),0,dbtags,audioctrl); break; case AHIDB_MaxPlaySamples: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,audioctrl->ahiac_MaxBuffSamples,dbtags,audioctrl); break; case AHIDB_MaxRecordSamples: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl); break; case AHIDB_MinMonitorVolume: case AHIDB_MaxMonitorVolume: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x00000,dbtags,audioctrl); break; case AHIDB_MinInputGain: case AHIDB_MaxInputGain: case AHIDB_MinOutputVolume: case AHIDB_MaxOutputVolume: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0x10000,dbtags,audioctrl); break; case AHIDB_Inputs: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,0,dbtags,audioctrl); break; case AHIDB_Outputs: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,1,dbtags,audioctrl); break; // Booleans that defaults to FALSE case AHIDB_Realtime: case AHIDB_Record: case AHIDB_FullDuplex: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,FALSE,dbtags,audioctrl); break; // Booleans that defaults to TRUE case AHIDB_PingPong: *ptr=AHIsub_GetAttr(tag1->ti_Tag,0,TRUE,dbtags,audioctrl); break; // Tags from the database. default: if((tag2=FindTagItem(tag1->ti_Tag,dbtags))) *ptr=tag2->ti_Data; break; } } } else // no AHIsubBase rc=FALSE; } else // no database taglist rc=FALSE; } else // no valid audioctrl rc=FALSE; if(id != AHI_INVALID_ID) AHIFreeVec(audioctrl); if(AHIsubBase) CloseLibrary(AHIsubBase); UnlockDatabase(audiodb); } else // unable to lock database rc=FALSE; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { KPrintF("=>%s\n", rc ? "TRUE" : "FALSE" ); } return (ULONG) rc; }
void Debug_SetEffect( ULONG *effect, struct AHIPrivAudioCtrl *audioctrl ) { KPrintF("AHI_SetEffect(0x%08lx (Effect 0x%08lx), 0x%08lx)\n", effect, *effect, audioctrl); }
ULONG ASMCALL DevOpen ( REG(d0, ULONG unit), REG(d1, ULONG flags), REG(a1, struct AHIRequest *ioreq), REG(a6, struct AHIBase *AHIBase) ) { ULONG rc = 0; BOOL error = FALSE; struct AHIDevUnit *iounit=NULL; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("OpenDevice(%ld, 0x%08lx, %ld)", unit, ioreq, flags); } // Check if size includes the ahir_Version field if(ioreq->ahir_Std.io_Message.mn_Length < (sizeof(struct IOStdReq) + 2)) { Req( "Bad parameters to OpenDevice()." ); ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; return IOERR_OPENFAIL; } // One more check... if((unit != AHI_NO_UNIT) && (ioreq->ahir_Version >= Version)) { if(ioreq->ahir_Std.io_Message.mn_Length < sizeof(struct AHIRequest)) { Req( "Bad parameters to OpenDevice()." ); ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; return IOERR_OPENFAIL; } } AHIBase->ahib_Library.lib_OpenCnt++; ObtainSemaphore(&AHIBase->ahib_Lock); if( ! (flags & AHIDF_NOMODESCAN)) { // Load database if not already loaded if(AHI_NextAudioID(AHI_INVALID_ID) == AHI_INVALID_ID) { AHI_LoadModeFile("DEVS:AudioModes"); } } if( ioreq->ahir_Version > Version) error=TRUE; else { if(unit < AHI_UNITS) { iounit=InitUnit(unit,AHIBase); if(!iounit) error=TRUE; } else if(unit == AHI_NO_UNIT) InitUnit(unit,AHIBase); } if(!error) { ioreq->ahir_Std.io_Unit=(struct Unit *) iounit; if(iounit) // Is NULL for AHI_NO_UNIT iounit->Unit.unit_OpenCnt++; AHIBase->ahib_Library.lib_OpenCnt++; AHIBase->ahib_Library.lib_Flags &=~LIBF_DELEXP; } else { rc=IOERR_OPENFAIL; ioreq->ahir_Std.io_Error=IOERR_OPENFAIL; ioreq->ahir_Std.io_Device=(struct Device *) -1; ioreq->ahir_Std.io_Unit=(struct Unit *) -1; } ReleaseSemaphore(&AHIBase->ahib_Lock); AHIBase->ahib_Library.lib_OpenCnt--; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_LOW) { KPrintF("=>%ld\n",rc); } return rc; }
ULONG AddAudioMode( struct TagItem* DBtags, struct AHIBase* AHIBase ) { struct AHI_AudioDatabase *audiodb; struct AHI_AudioMode *node; ULONG nodesize = sizeof(struct AHI_AudioMode), tagitems = 0; ULONG datalength = 0, namelength = 0, driverlength = 0; struct TagItem *tstate = DBtags, *tp, *tag; ULONG rc = FALSE; if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { Debug_AddAudioMode(DBtags); } // Remove old mode if present in database AHI_RemoveAudioMode( GetTagData(AHIDB_AudioID, AHI_INVALID_ID, DBtags)); // Now add the new mode audiodb = LockDatabaseWrite(); if(audiodb != NULL) { BOOL fast = FALSE; // Find total size while( (tag = NextTagItem(&tstate)) != NULL ) { if(tag->ti_Data) switch(tag->ti_Tag) { case AHIDB_Data: datalength = ((ULONG *)tag->ti_Data)[0]; nodesize += datalength; break; case AHIDB_Name: namelength = strlen((UBYTE *)tag->ti_Data)+1; nodesize += namelength; break; case AHIDB_Driver: driverlength = strlen((UBYTE *)tag->ti_Data)+1; nodesize += driverlength; break; case AHIDB_MultTable: fast = tag->ti_Data; break; } nodesize += sizeof(struct TagItem); tagitems++; } if( fast ) { // Silently filter away all fast modes! rc = TRUE; goto unlock; } nodesize += sizeof(struct TagItem); // The last TAG_END tagitems++; node = AllocVec(nodesize, MEMF_PUBLIC|MEMF_CLEAR); if(node != NULL) { tp = node->ahidbn_Tags; tstate = DBtags; while( (tag = NextTagItem(&tstate)) != NULL) { if(tag->ti_Data) switch(tag->ti_Tag) { case AHIDB_Data: tp->ti_Data = ((ULONG) &node->ahidbn_Tags[tagitems]); CopyMem((APTR)tag->ti_Data, (APTR)tp->ti_Data, datalength); break; case AHIDB_Name: tp->ti_Data = ((ULONG) &node->ahidbn_Tags[tagitems]) + datalength; strcpy((UBYTE *)tp->ti_Data, (UBYTE *)tag->ti_Data); break; case AHIDB_Driver: tp->ti_Data= ((ULONG) &node->ahidbn_Tags[tagitems]) + datalength + namelength; strcpy((UBYTE *)tp->ti_Data, (UBYTE *)tag->ti_Data); break; default: tp->ti_Data = tag->ti_Data; break; } tp->ti_Tag = tag->ti_Tag; tp++; } tp->ti_Tag = TAG_DONE; AddHead((struct List *) &audiodb->ahidb_AudioModes, (struct Node *) node); rc = TRUE; } unlock: UnlockDatabase(audiodb); } if(AHIBase->ahib_DebugLevel >= AHI_DEBUG_HIGH) { KPrintF("=>%ld\n",rc); } return rc; }