revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Drivers / Device / device-playslave.c
blobea201829ff351f1183559d676bfe9ea6fb8b8027
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 BOOL running;
60 ULONG signals;
62 /* Note that in OS4, we cannot call FindTask(NULL) here, since IExec
63 * is inside AHIsubBase! */
64 AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask(NULL)->tc_UserData;
65 AHIsubBase = (struct DriverBase*) dd->ahisubbase;
67 dd->slavesignal = AllocSignal( -1 );
69 if( dd->slavesignal != -1 )
71 struct MsgPort* ahi_mp = NULL;
72 struct AHIRequest* ahi_iorequest = NULL;
73 APTR ahi_iocopy = NULL;
74 BYTE ahi_device = -1;
76 struct AHIRequest* ahi_io[ 2 ] = { NULL, NULL };
77 BOOL ahi_io_used[ 2 ] = { FALSE, FALSE };
79 ULONG frame_length = 0;
81 ahi_mp = CreateMsgPort();
83 if( ahi_mp != NULL )
85 ahi_iorequest = (struct AHIRequest*) CreateIORequest( ahi_mp, sizeof( struct AHIRequest ) );
87 if( ahi_iorequest != NULL )
89 ahi_iorequest->ahir_Version = 4;
91 ahi_device = OpenDevice( AHINAME, dd->unit,
92 (struct IORequest*) ahi_iorequest, 0 );
94 if( ahi_device == 0 )
96 struct Library* AHIBase = (struct Library*) ahi_iorequest->ahir_Std.io_Device;
97 #ifdef __AMIGAOS4__
98 struct AHIIFace* IAHI = (struct AHIIFace*) GetInterface(AHIBase, "main", 1, NULL);
99 #endif
101 ahi_iocopy = AllocVec( sizeof( *ahi_iorequest ), MEMF_ANY );
103 if( ahi_iocopy != NULL )
105 bcopy( ahi_iorequest, ahi_iocopy, sizeof( *ahi_iorequest ) );
107 ahi_io[ 0 ] = ahi_iorequest;
108 ahi_io[ 1 ] = ahi_iocopy;
110 // Everything set up. Tell Master we're alive and healthy.
112 Signal( (struct Task*) dd->mastertask,
113 1L << dd->mastersignal );
115 running = TRUE;
117 // The main playback loop follow
119 while( running )
121 int skip_mix;
122 APTR tmp_buff;
123 struct AHIRequest* tmp_io;
125 if( ahi_io_used[ 0 ] )
127 LONG err;
128 ULONG mask = ( SIGBREAKF_CTRL_C |
129 (1L << dd->slavesignal) |
130 (1L << ahi_mp->mp_SigBit) );
132 signals = Wait( mask );
134 if( signals & ( SIGBREAKF_CTRL_C |
135 (1L << dd->slavesignal) ) )
137 running = FALSE;
138 break;
141 err = WaitIO( (struct IORequest*) ahi_io[ 0 ] );
143 if( err != 0 )
145 KPrintF( DRIVER ": AHI device error %ld\n", err );
146 // running = FALSE;
147 break;
151 skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc,
152 (Object*) AudioCtrl, 0 );
154 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
156 if( ! skip_mix )
158 CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl,
159 dd->mixbuffers[ 0 ] );
162 CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
164 if( frame_length == 0 )
166 frame_length = AHI_SampleFrameSize( AudioCtrl->ahiac_BuffType );
169 ahi_io[ 0 ]->ahir_Std.io_Command = CMD_WRITE;
170 ahi_io[ 0 ]->ahir_Std.io_Data = dd->mixbuffers[ 0 ];
171 ahi_io[ 0 ]->ahir_Std.io_Length = ( AudioCtrl->ahiac_BuffSamples *
172 frame_length );
173 ahi_io[ 0 ]->ahir_Std.io_Offset = 0;
174 ahi_io[ 0 ]->ahir_Frequency = AudioCtrl->ahiac_MixFreq;
175 ahi_io[ 0 ]->ahir_Type = AudioCtrl->ahiac_BuffType;
176 ahi_io[ 0 ]->ahir_Volume = 0x10000;
177 ahi_io[ 0 ]->ahir_Position = 0x08000;
178 ahi_io[ 0 ]->ahir_Link = ( ahi_io_used[ 1 ] ?
179 ahi_io[ 1 ] : NULL );
181 SendIO( (struct IORequest*) ahi_io[ 0 ] );
183 tmp_io = ahi_io[ 0 ];
184 ahi_io[ 0 ] = ahi_io[ 1 ];
185 ahi_io[ 1 ] = tmp_io;
187 tmp_buff = dd->mixbuffers[ 0 ];
188 dd->mixbuffers[ 0 ] = dd->mixbuffers[ 1 ];
189 dd->mixbuffers[ 1 ] = tmp_buff;
191 ahi_io_used[ 0 ] = ahi_io_used[ 1 ];
192 ahi_io_used[ 1 ] = TRUE;
196 if( ahi_io_used[ 0 ] )
198 AbortIO( (struct IORequest*) ahi_io[ 0 ] );
199 WaitIO( (struct IORequest*) ahi_io[ 0 ] );
202 if( ahi_io_used[ 1 ] )
204 AbortIO( (struct IORequest*) ahi_io[ 1 ] );
205 WaitIO( (struct IORequest*) ahi_io[ 1 ] );
208 FreeVec( ahi_iocopy );
211 #ifdef __AMIGAOS4__
212 DropInterface((struct Interface*) IAHI);
213 #endif
214 CloseDevice( (struct IORequest*) ahi_iorequest );
217 DeleteIORequest( (struct IORequest*) ahi_iorequest );
220 DeleteMsgPort( ahi_mp );
224 FreeSignal( dd->slavesignal );
225 dd->slavesignal = -1;
227 Forbid();
229 // Tell the Master we're dying
231 Signal( (struct Task*) dd->mastertask,
232 1L << dd->mastersignal );
234 dd->slavetask = NULL;
236 // Multitasking will resume when we are dead.