3 * This is a driver for ahi.device loopback sound
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>
20 #include "DriverData.h"
22 #define dd ((struct DeviceData*) AudioCtrl->ahiac_DriverData)
27 PROCGW( static, void, slaveentry
, SlaveEntry
);
29 static const LONG frequencies
[] =
31 8000, // ยต- and A-Law (telephone)
38 #define FREQUENCIES (sizeof frequencies / sizeof frequencies[ 0 ])
40 /******************************************************************************
41 ** AHIsub_AllocAudio **********************************************************
42 ******************************************************************************/
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
);
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;
69 if( dd
->mastersignal
== -1 )
75 // TODO open ahi.device
77 AudioCtrl
->ahiac_MixFreq
= freq
;
79 return ( AHISF_KNOWHIFI
|
86 /******************************************************************************
87 ** AHIsub_FreeAudio ***********************************************************
88 ******************************************************************************/
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 ******************************************************************************/
108 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
109 struct DriverBase
* AHIsubBase
)
111 // V6 drivers do not have to preserve all registers
117 /******************************************************************************
118 ** AHIsub_Enable **************************************************************
119 ******************************************************************************/
122 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
123 struct DriverBase
* AHIsubBase
)
125 // V6 drivers do not have to preserve all registers
131 /******************************************************************************
132 ** AHIsub_Start ***************************************************************
133 ******************************************************************************/
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 },
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
;
167 dd
->slavetask
= CreateNewProc( proctags
);
169 if( dd
->slavetask
!= NULL
)
171 dd
->slavetask
->pr_Task
.tc_UserData
= AudioCtrl
;
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?
187 return AHIE_NOMEM
; // Well, out of memory or whatever...
191 if( flags
& AHISF_RECORD
)
200 /******************************************************************************
201 ** AHIsub_Update **************************************************************
202 ******************************************************************************/
205 _AHIsub_Update( ULONG flags
,
206 struct AHIAudioCtrlDrv
* AudioCtrl
,
207 struct DriverBase
* AHIsubBase
)
213 /******************************************************************************
214 ** AHIsub_Stop ****************************************************************
215 ******************************************************************************/
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
)
248 /******************************************************************************
249 ** AHIsub_GetAttr *************************************************************
250 ******************************************************************************/
253 _AHIsub_GetAttr( ULONG attribute
,
256 struct TagItem
* taglist
,
257 struct AHIAudioCtrlDrv
* AudioCtrl
,
258 struct DriverBase
* AHIsubBase
)
267 case AHIDB_Frequencies
:
270 case AHIDB_Frequency
: // Index->Frequency
271 return (LONG
) frequencies
[ argument
];
273 case AHIDB_Index
: // Frequency->Index
274 if( argument
<= frequencies
[ 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
) )
300 return 0; // Will not happen
303 return (IPTR
) "Martin 'Leviticus' Blom";
305 case AHIDB_Copyright
:
306 return (IPTR
) "Public Domain";
309 return (IPTR
) LibIDString
;
321 return (IPTR
) "Device"; // We have only one "output"!
329 /******************************************************************************
330 ** AHIsub_HardwareControl *****************************************************
331 ******************************************************************************/
334 _AHIsub_HardwareControl( ULONG attribute
,
336 struct AHIAudioCtrlDrv
* AudioCtrl
,
337 struct DriverBase
* AHIsubBase
)