Do not access SysBase->ThisTask outside exec.library. The code should not rely on...
[AROS.git] / workbench / devs / AHI / Drivers / Device / device-playslave.c
blobfc724757a5ca992fdc4c31339e7f18004d87cd37
2 #include <config.h>
4 #include <devices/ahi.h>
5 #include <dos/dos.h>
6 #include <exec/execbase.h>
7 #include <libraries/ahi_sub.h>
8 #include <proto/ahi.h>
9 #include <proto/exec.h>
10 #include <proto/utility.h>
12 #include <string.h>
14 #include "DriverData.h"
15 #include "library.h"
17 #define dd ((struct DeviceData*) AudioCtrl->ahiac_DriverData)
19 /******************************************************************************
20 ** The slave process **********************************************************
21 ******************************************************************************/
23 #undef SysBase
25 static void Slave( struct ExecBase* SysBase );
27 #if defined( __AROS__ )
29 #include <aros/asmcall.h>
31 AROS_UFH3(LONG, SlaveEntry,
32 AROS_UFHA(STRPTR, argPtr, A0),
33 AROS_UFHA(ULONG, argSize, D0),
34 AROS_UFHA(struct ExecBase *, SysBase, A6))
36 AROS_USERFUNC_INIT
37 Slave( SysBase );
38 return 0;
39 AROS_USERFUNC_EXIT
42 #else
44 void SlaveEntry(void)
46 struct ExecBase* SysBase = *((struct ExecBase**) 4);
48 Slave( SysBase );
51 #endif
54 static void
55 Slave( struct ExecBase* SysBase )
57 struct AHIAudioCtrlDrv* AudioCtrl;
58 struct DriverBase* AHIsubBase;
59 struct DeviceBase* DeviceBase;
60 BOOL running;
61 ULONG signals;
63 /* Note that in OS4, we cannot call FindTask(NULL) here, since IExec
64 * is inside AHIsubBase! */
65 AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask(NULL)->tc_UserData;
66 AHIsubBase = (struct DriverBase*) dd->ahisubbase;
67 DeviceBase = (struct DeviceBase*) AHIsubBase;
69 dd->slavesignal = AllocSignal( -1 );
71 if( dd->slavesignal != -1 )
73 struct MsgPort* ahi_mp = NULL;
74 struct AHIRequest* ahi_iorequest = NULL;
75 APTR ahi_iocopy = NULL;
76 BYTE ahi_device = -1;
78 struct AHIRequest* ahi_io[ 2 ] = { NULL, NULL };
79 BOOL ahi_io_used[ 2 ] = { FALSE, FALSE };
81 ULONG frame_length = 0;
83 ahi_mp = CreateMsgPort();
85 if( ahi_mp != NULL )
87 ahi_iorequest = (struct AHIRequest*) CreateIORequest( ahi_mp, sizeof( struct AHIRequest ) );
89 if( ahi_iorequest != NULL )
91 ahi_iorequest->ahir_Version = 4;
93 ahi_device = OpenDevice( AHINAME, dd->unit,
94 (struct IORequest*) ahi_iorequest, 0 );
96 if( ahi_device == 0 )
98 struct Library* AHIBase = (struct Library*) ahi_iorequest->ahir_Std.io_Device;
99 #ifdef __AMIGAOS4__
100 struct AHIIFace* IAHI = (struct AHIIFace*) GetInterface(AHIBase, "main", 1, NULL);
101 #endif
103 ahi_iocopy = AllocVec( sizeof( *ahi_iorequest ), MEMF_ANY );
105 if( ahi_iocopy != NULL )
107 bcopy( ahi_iorequest, ahi_iocopy, sizeof( *ahi_iorequest ) );
109 ahi_io[ 0 ] = ahi_iorequest;
110 ahi_io[ 1 ] = ahi_iocopy;
112 // Everything set up. Tell Master we're alive and healthy.
114 Signal( (struct Task*) dd->mastertask,
115 1L << dd->mastersignal );
117 running = TRUE;
119 // The main playback loop follow
121 while( running )
123 int skip_mix;
124 APTR tmp_buff;
125 struct AHIRequest* tmp_io;
127 if( ahi_io_used[ 0 ] )
129 LONG err;
130 ULONG mask = ( SIGBREAKF_CTRL_C |
131 (1L << dd->slavesignal) |
132 (1L << ahi_mp->mp_SigBit) );
134 signals = Wait( mask );
136 if( signals & ( SIGBREAKF_CTRL_C |
137 (1L << dd->slavesignal) ) )
139 running = FALSE;
140 break;
143 err = WaitIO( (struct IORequest*) ahi_io[ 0 ] );
145 if( err != 0 )
147 KPrintF( DRIVER ": AHI device error %ld\n", err );
148 // running = FALSE;
149 break;
153 skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc,
154 (Object*) AudioCtrl, 0 );
156 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
158 if( ! skip_mix )
160 CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl,
161 dd->mixbuffers[ 0 ] );
164 CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
166 if( frame_length == 0 )
168 frame_length = AHI_SampleFrameSize( AudioCtrl->ahiac_BuffType );
171 ahi_io[ 0 ]->ahir_Std.io_Command = CMD_WRITE;
172 ahi_io[ 0 ]->ahir_Std.io_Data = dd->mixbuffers[ 0 ];
173 ahi_io[ 0 ]->ahir_Std.io_Length = ( AudioCtrl->ahiac_BuffSamples *
174 frame_length );
175 ahi_io[ 0 ]->ahir_Std.io_Offset = 0;
176 ahi_io[ 0 ]->ahir_Frequency = AudioCtrl->ahiac_MixFreq;
177 ahi_io[ 0 ]->ahir_Type = AudioCtrl->ahiac_BuffType;
178 ahi_io[ 0 ]->ahir_Volume = 0x10000;
179 ahi_io[ 0 ]->ahir_Position = 0x08000;
180 ahi_io[ 0 ]->ahir_Link = ( ahi_io_used[ 1 ] ?
181 ahi_io[ 1 ] : NULL );
183 SendIO( (struct IORequest*) ahi_io[ 0 ] );
185 tmp_io = ahi_io[ 0 ];
186 ahi_io[ 0 ] = ahi_io[ 1 ];
187 ahi_io[ 1 ] = tmp_io;
189 tmp_buff = dd->mixbuffers[ 0 ];
190 dd->mixbuffers[ 0 ] = dd->mixbuffers[ 1 ];
191 dd->mixbuffers[ 1 ] = tmp_buff;
193 ahi_io_used[ 0 ] = ahi_io_used[ 1 ];
194 ahi_io_used[ 1 ] = TRUE;
198 if( ahi_io_used[ 0 ] )
200 AbortIO( (struct IORequest*) ahi_io[ 0 ] );
201 WaitIO( (struct IORequest*) ahi_io[ 0 ] );
204 if( ahi_io_used[ 1 ] )
206 AbortIO( (struct IORequest*) ahi_io[ 1 ] );
207 WaitIO( (struct IORequest*) ahi_io[ 1 ] );
210 FreeVec( ahi_iocopy );
213 #ifdef __AMIGAOS4__
214 DropInterface((struct Interface*) IAHI);
215 #endif
216 CloseDevice( (struct IORequest*) ahi_iorequest );
219 DeleteIORequest( (struct IORequest*) ahi_iorequest );
222 DeleteMsgPort( ahi_mp );
226 FreeSignal( dd->slavesignal );
227 dd->slavesignal = -1;
229 Forbid();
231 // Tell the Master we're dying
233 Signal( (struct Task*) dd->mastertask,
234 1L << dd->mastersignal );
236 dd->slavetask = NULL;
238 // Multitaking will resume when we are dead.