2 Copyright © 2015, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
9 #include <devices/ahi.h>
10 #include <exec/execbase.h>
11 #include <libraries/ahi_sub.h>
13 #include "DriverData.h"
16 #include "alsa-bridge/alsa.h"
18 #define dd ((struct AlsaData*) AudioCtrl->ahiac_DriverData)
20 #define min(a,b) ( (a) < (b) ? (a) : (b) )
22 /******************************************************************************
23 ** The slave process **********************************************************
24 ******************************************************************************/
28 void Slave( struct ExecBase
* SysBase
);
30 #include <aros/asmcall.h>
32 AROS_UFH3(LONG
, SlaveEntry
,
33 AROS_UFHA(STRPTR
, argPtr
, A0
),
34 AROS_UFHA(ULONG
, argSize
, D0
),
35 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
42 #include <hardware/intbits.h>
43 #include <proto/timer.h>
45 AROS_INTH1(AHITimerTickCode
, struct Task
*, task
)
48 Signal(task
, SIGBREAKF_CTRL_F
);
56 static void SmallDelay(struct ExecBase
*SysBase
)
60 i
.is_Code
= (APTR
)AHITimerTickCode
;
61 i
.is_Data
= FindTask(0);
62 i
.is_Node
.ln_Name
= "AROS AHI Driver Timer Tick Server";
64 i
.is_Node
.ln_Type
= NT_INTERRUPT
;
66 SetSignal(0, SIGBREAKF_CTRL_F
);
67 AddIntServer(INTB_VERTB
, &i
);
68 Wait(SIGBREAKF_CTRL_F
);
69 RemIntServer(INTB_VERTB
, &i
);
73 Slave( struct ExecBase
* SysBase
)
75 struct AHIAudioCtrlDrv
* AudioCtrl
;
76 struct DriverBase
* AHIsubBase
;
77 struct AlsaBase
* AlsaBase
;
81 APTR framesptr
= NULL
;
83 AudioCtrl
= (struct AHIAudioCtrlDrv
*) FindTask(NULL
)->tc_UserData
;
84 AHIsubBase
= (struct DriverBase
*) dd
->ahisubbase
;
85 AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
87 dd
->slavesignal
= AllocSignal( -1 );
89 if( dd
->slavesignal
!= -1 )
91 // Everything set up. Tell Master we're alive and healthy.
93 Signal( (struct Task
*) dd
->mastertask
,
94 1L << dd
->mastersignal
);
100 signals
= SetSignal(0L,0L);
102 if( signals
& ( SIGBREAKF_CTRL_C
| (1L << dd
->slavesignal
) ) )
113 framesfree
= ALSA_Avail(dd
->alsahandle
);
114 if (framesfree
== ALSA_XRUN
)
116 D(bug("[Alsa] ALSA_Avail() == XRUN\n"));
117 ALSA_Prepare(dd
->alsahandle
);
118 framesfree
= ALSA_Avail(dd
->alsahandle
);
121 if (framesfree
>= 64)
124 if (framesfree
>= AudioCtrl
->ahiac_BuffSamples
)
132 /* Loop until alsa buffer is filled */
133 while (framesfree
> 0)
137 if (framesready
== 0)
142 CallHookPkt(AudioCtrl
->ahiac_PlayerFunc
, AudioCtrl
, NULL
);
143 CallHookPkt(AudioCtrl
->ahiac_MixerFunc
, AudioCtrl
, dd
->mixbuffer
);
144 framesready
= AudioCtrl
->ahiac_BuffSamples
;
145 framesptr
= dd
->mixbuffer
;
149 written
= ALSA_Write(dd
->alsahandle
, framesptr
, min(framesready
,
151 if (written
== ALSA_XRUN
)
153 D(bug("[Alsa] ALSA_Write() == XRUN %d, %d\n", framesfree
, framesready
));
154 ALSA_Prepare(dd
->alsahandle
);
155 written
= ALSA_Write(dd
->alsahandle
, framesptr
, min(framesready
,
159 framesready
-= written
;
160 framesfree
-= written
;
161 framesptr
+= written
* 4;
163 CallHookA(AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0);
169 FreeSignal( dd
->slavesignal
);
170 dd
->slavesignal
= -1;
174 // Tell the Master we're dying
176 Signal( (struct Task
*) dd
->mastertask
, 1L << dd
->mastersignal
);
178 dd
->slavetask
= NULL
;
180 // Multitaking will resume when we are dead.