revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Drivers / Device / device-main.c
blob64be2401849781b192d070157e5b3ee75be40e30
2 /*
3 * This is a driver for ahi.device loopback sound
4 */
6 #include <config.h>
8 #include <devices/ahi.h>
9 #include <dos/dostags.h>
10 #include <exec/memory.h>
11 #include <libraries/ahi_sub.h>
12 #include <proto/ahi_sub.h>
13 #include <proto/exec.h>
14 #include <proto/dos.h>
15 #include <proto/utility.h>
17 #include <stddef.h>
19 #include "library.h"
20 #include "DriverData.h"
22 #define dd ((struct DeviceData*) AudioCtrl->ahiac_DriverData)
24 void
25 SlaveEntry( void );
27 PROCGW( static, void, slaveentry, SlaveEntry );
29 static const LONG frequencies[] =
31 8000, // ยต- and A-Law (telephone)
32 11025, // CD/4
33 22050, // CD/2
34 44100, // CD
35 48000, // DAT
38 #define FREQUENCIES (sizeof frequencies / sizeof frequencies[ 0 ])
40 /******************************************************************************
41 ** AHIsub_AllocAudio **********************************************************
42 ******************************************************************************/
44 ULONG
45 _AHIsub_AllocAudio( struct TagItem* taglist,
46 struct AHIAudioCtrlDrv* AudioCtrl,
47 struct DriverBase* AHIsubBase )
49 struct DeviceBase* DeviceBase = (struct DeviceBase*) AHIsubBase;
50 int freq = AudioCtrl->ahiac_MixFreq;
52 AudioCtrl->ahiac_DriverData = AllocVec( sizeof( struct DeviceData ),
53 MEMF_CLEAR | MEMF_PUBLIC );
55 if( dd != NULL )
57 dd->slavesignal = -1;
58 dd->mastersignal = AllocSignal( -1 );
59 dd->mastertask = (struct Process*) FindTask( NULL );
60 dd->ahisubbase = DeviceBase;
61 dd->unit = (GetTagData( AHIDB_AudioID, 0, taglist) & 0x0000f000) >> 12;
64 else
66 return AHISF_ERROR;
69 if( dd->mastersignal == -1 )
71 return AHISF_ERROR;
75 // TODO open ahi.device
77 AudioCtrl->ahiac_MixFreq = freq;
79 return ( AHISF_KNOWHIFI |
80 AHISF_KNOWSTEREO |
81 AHISF_MIXING |
82 AHISF_TIMING );
86 /******************************************************************************
87 ** AHIsub_FreeAudio ***********************************************************
88 ******************************************************************************/
90 void
91 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv* AudioCtrl,
92 struct DriverBase* AHIsubBase )
94 if( AudioCtrl->ahiac_DriverData != NULL )
96 FreeSignal( dd->mastersignal );
97 FreeVec( AudioCtrl->ahiac_DriverData );
98 AudioCtrl->ahiac_DriverData = NULL;
103 /******************************************************************************
104 ** AHIsub_Disable *************************************************************
105 ******************************************************************************/
107 void
108 _AHIsub_Disable( struct AHIAudioCtrlDrv* AudioCtrl,
109 struct DriverBase* AHIsubBase )
111 // V6 drivers do not have to preserve all registers
113 Forbid();
117 /******************************************************************************
118 ** AHIsub_Enable **************************************************************
119 ******************************************************************************/
121 void
122 _AHIsub_Enable( struct AHIAudioCtrlDrv* AudioCtrl,
123 struct DriverBase* AHIsubBase )
125 // V6 drivers do not have to preserve all registers
127 Permit();
131 /******************************************************************************
132 ** AHIsub_Start ***************************************************************
133 ******************************************************************************/
135 ULONG
136 _AHIsub_Start( ULONG flags,
137 struct AHIAudioCtrlDrv* AudioCtrl,
138 struct DriverBase* AHIsubBase )
140 struct DeviceBase* DeviceBase = (struct DeviceBase*) AHIsubBase;
142 AHIsub_Stop( flags, AudioCtrl );
144 if(flags & AHISF_PLAY)
146 struct TagItem proctags[] =
148 { NP_Entry, (IPTR)&slaveentry },
149 { NP_Name, (IPTR)LibName },
150 { NP_Priority, 127 },
151 { TAG_DONE, 0 }
155 dd->mixbuffers[ 0 ] = AllocVec( AudioCtrl->ahiac_BuffSize,
156 MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC );
158 if( dd->mixbuffers[ 0 ] == NULL ) return AHIE_NOMEM;
160 dd->mixbuffers[ 1 ] = AllocVec( AudioCtrl->ahiac_BuffSize,
161 MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC );
163 if( dd->mixbuffers[ 1 ] == NULL ) return AHIE_NOMEM;
165 Forbid();
167 dd->slavetask = CreateNewProc( proctags );
169 if( dd->slavetask != NULL )
171 dd->slavetask->pr_Task.tc_UserData = AudioCtrl;
174 Permit();
176 if( dd->slavetask != NULL )
178 Wait( 1L << dd->mastersignal ); // Wait for slave to come alive
180 if( dd->slavetask == NULL ) // Is slave alive or dead?
182 return AHIE_UNKNOWN;
185 else
187 return AHIE_NOMEM; // Well, out of memory or whatever...
191 if( flags & AHISF_RECORD )
193 return AHIE_UNKNOWN;
196 return AHIE_OK;
200 /******************************************************************************
201 ** AHIsub_Update **************************************************************
202 ******************************************************************************/
204 void
205 _AHIsub_Update( ULONG flags,
206 struct AHIAudioCtrlDrv* AudioCtrl,
207 struct DriverBase* AHIsubBase )
209 // Empty function
213 /******************************************************************************
214 ** AHIsub_Stop ****************************************************************
215 ******************************************************************************/
217 void
218 _AHIsub_Stop( ULONG flags,
219 struct AHIAudioCtrlDrv* AudioCtrl,
220 struct DriverBase* AHIsubBase )
222 if( flags & AHISF_PLAY )
224 if( dd->slavetask != NULL )
226 if( dd->slavesignal != -1 )
228 Signal( (struct Task*) dd->slavetask,
229 1L << dd->slavesignal ); // Kill him!
232 Wait( 1L << dd->mastersignal ); // Wait for slave to die
235 FreeVec( dd->mixbuffers[ 0 ] );
236 FreeVec( dd->mixbuffers[ 1 ] );
237 dd->mixbuffers[ 0 ] = NULL;
238 dd->mixbuffers[ 1 ] = NULL;
241 if(flags & AHISF_RECORD)
243 // Do nothing
248 /******************************************************************************
249 ** AHIsub_GetAttr *************************************************************
250 ******************************************************************************/
252 IPTR
253 _AHIsub_GetAttr( ULONG attribute,
254 LONG argument,
255 IPTR def,
256 struct TagItem* taglist,
257 struct AHIAudioCtrlDrv* AudioCtrl,
258 struct DriverBase* AHIsubBase )
260 size_t i;
262 switch( attribute )
264 case AHIDB_Bits:
265 return 16;
267 case AHIDB_Frequencies:
268 return FREQUENCIES;
270 case AHIDB_Frequency: // Index->Frequency
271 return (LONG) frequencies[ argument ];
273 case AHIDB_Index: // Frequency->Index
274 if( argument <= frequencies[ 0 ] )
276 return 0;
279 if( argument >= frequencies[ FREQUENCIES - 1 ] )
281 return FREQUENCIES - 1;
284 for( i = 1; i < FREQUENCIES; i++ )
286 if( frequencies[ i ] > argument )
288 if( ( argument - frequencies[ i - 1 ] ) <
289 ( frequencies[ i ] - argument ) )
291 return i-1;
293 else
295 return i;
300 return 0; // Will not happen
302 case AHIDB_Author:
303 return (IPTR) "Martin 'Leviticus' Blom";
305 case AHIDB_Copyright:
306 return (IPTR) "Public Domain";
308 case AHIDB_Version:
309 return (IPTR) LibIDString;
311 case AHIDB_Record:
312 return TRUE;
314 case AHIDB_Realtime:
315 return TRUE;
317 case AHIDB_Outputs:
318 return 1;
320 case AHIDB_Output:
321 return (IPTR) "Device"; // We have only one "output"!
323 default:
324 return def;
329 /******************************************************************************
330 ** AHIsub_HardwareControl *****************************************************
331 ******************************************************************************/
333 ULONG
334 _AHIsub_HardwareControl( ULONG attribute,
335 LONG argument,
336 struct AHIAudioCtrlDrv* AudioCtrl,
337 struct DriverBase* AHIsubBase )
339 return 0;