3 * This is a do-nothing example AHI driver that just discards the
4 * sound data that is sent to it. Recording is not supported.
9 #include <devices/ahi.h>
10 #include <dos/dostags.h>
11 #include <exec/memory.h>
12 #include <libraries/ahi_sub.h>
13 #include <proto/ahi_sub.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/utility.h>
21 #include "DriverData.h"
23 #define dd ((struct VoidData*) AudioCtrl->ahiac_DriverData)
28 PROCGW( static, void, slaveentry
, SlaveEntry
);
31 /* There is probably no reason to support all these frequencies. If,
32 * for example, your hardware is locked at 48 kHz, it's ok to only
33 * present one single mixing/recording frequency to the user. If your
34 * hardware has internal resamples and accept any frequency, select a
38 static const LONG frequencies
[] =
41 8000, // ยต- and A-Law (telephone)
43 10000, // VHS monaural track
51 20000, // VHS Hi-Fi/Video track
54 27429, // Highest Paula/OCS frequency
56 31968, // NTSC FM 2-3 pull-down
58 32032, // NTSC FM 2-3 pull-up
61 44056, // NTSC CD 2-3 pull-down
63 44144, // NTSC CD 2-3 pull-up
64 47952, // NTSC DAT 2-3 pull-down
66 48048, // NTSC DAT 2-3 pull-up
71 #define FREQUENCIES (sizeof frequencies / sizeof frequencies[ 0 ])
73 /******************************************************************************
74 ** AHIsub_AllocAudio **********************************************************
75 ******************************************************************************/
78 _AHIsub_AllocAudio( struct TagItem
* taglist
,
79 struct AHIAudioCtrlDrv
* AudioCtrl
,
80 struct DriverBase
* AHIsubBase
)
82 struct VoidBase
* VoidBase
= (struct VoidBase
*) AHIsubBase
;
84 // NOTE! A Real sound card driver would allocate *and lock* the
85 // audio hardware here. If this function gets called a second time,
86 // and the hardware is not capable of handling several audio streams
87 // at the same time, return AHISF_ERROR now!
89 AudioCtrl
->ahiac_DriverData
= AllocVec( sizeof( struct VoidData
),
90 MEMF_CLEAR
| MEMF_PUBLIC
);
95 dd
->mastersignal
= AllocSignal( -1 );
96 dd
->mastertask
= (struct Process
*) FindTask( NULL
);
97 dd
->ahisubbase
= VoidBase
;
104 if( dd
->mastersignal
== -1 )
109 return ( AHISF_KNOWHIFI
|
111 AHISF_KNOWMULTICHANNEL
|
117 /******************************************************************************
118 ** AHIsub_FreeAudio ***********************************************************
119 ******************************************************************************/
122 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
123 struct DriverBase
* AHIsubBase
)
125 if( AudioCtrl
->ahiac_DriverData
!= NULL
)
127 FreeSignal( dd
->mastersignal
);
128 FreeVec( AudioCtrl
->ahiac_DriverData
);
129 AudioCtrl
->ahiac_DriverData
= NULL
;
134 /******************************************************************************
135 ** AHIsub_Disable *************************************************************
136 ******************************************************************************/
139 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
140 struct DriverBase
* AHIsubBase
)
142 // V6 drivers do not have to preserve all registers
148 /******************************************************************************
149 ** AHIsub_Enable **************************************************************
150 ******************************************************************************/
153 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
154 struct DriverBase
* AHIsubBase
)
156 // V6 drivers do not have to preserve all registers
162 /******************************************************************************
163 ** AHIsub_Start ***************************************************************
164 ******************************************************************************/
167 _AHIsub_Start( ULONG flags
,
168 struct AHIAudioCtrlDrv
* AudioCtrl
,
169 struct DriverBase
* AHIsubBase
)
171 struct VoidBase
* VoidBase
= (struct VoidBase
*) AHIsubBase
;
173 AHIsub_Stop( flags
, AudioCtrl
);
175 if(flags
& AHISF_PLAY
)
177 struct TagItem proctags
[] =
179 { NP_Entry
, (IPTR
) &slaveentry
},
180 { NP_Name
, (IPTR
) LibName
},
185 dd
->mixbuffer
= AllocVec( AudioCtrl
->ahiac_BuffSize
,
186 MEMF_ANY
| MEMF_PUBLIC
);
188 if( dd
->mixbuffer
== NULL
) return AHIE_NOMEM
;
192 dd
->slavetask
= CreateNewProc( proctags
);
194 if( dd
->slavetask
!= NULL
)
196 dd
->slavetask
->pr_Task
.tc_UserData
= AudioCtrl
;
201 if( dd
->slavetask
!= NULL
)
203 Wait( 1L << dd
->mastersignal
); // Wait for slave to come alive
205 if( dd
->slavetask
== NULL
) // Is slave alive or dead?
212 return AHIE_NOMEM
; // Well, out of memory or whatever...
216 if( flags
& AHISF_RECORD
)
225 /******************************************************************************
226 ** AHIsub_Update **************************************************************
227 ******************************************************************************/
230 _AHIsub_Update( ULONG flags
,
231 struct AHIAudioCtrlDrv
* AudioCtrl
,
232 struct DriverBase
* AHIsubBase
)
238 /******************************************************************************
239 ** AHIsub_Stop ****************************************************************
240 ******************************************************************************/
243 _AHIsub_Stop( ULONG flags
,
244 struct AHIAudioCtrlDrv
* AudioCtrl
,
245 struct DriverBase
* AHIsubBase
)
247 if( flags
& AHISF_PLAY
)
249 if( dd
->slavetask
!= NULL
)
251 if( dd
->slavesignal
!= -1 )
253 Signal( (struct Task
*) dd
->slavetask
,
254 1L << dd
->slavesignal
); // Kill him!
257 Wait( 1L << dd
->mastersignal
); // Wait for slave to die
260 FreeVec( dd
->mixbuffer
);
261 dd
->mixbuffer
= NULL
;
264 if(flags
& AHISF_RECORD
)
271 /******************************************************************************
272 ** AHIsub_GetAttr *************************************************************
273 ******************************************************************************/
276 _AHIsub_GetAttr( ULONG attribute
,
279 struct TagItem
* taglist
,
280 struct AHIAudioCtrlDrv
* AudioCtrl
,
281 struct DriverBase
* AHIsubBase
)
290 case AHIDB_Frequencies
:
293 case AHIDB_Frequency
: // Index->Frequency
294 return (LONG
) frequencies
[ argument
];
296 case AHIDB_Index
: // Frequency->Index
297 if( argument
<= frequencies
[ 0 ] )
302 if( argument
>= frequencies
[ FREQUENCIES
- 1 ] )
304 return FREQUENCIES
- 1;
307 for( i
= 1; i
< FREQUENCIES
; i
++ )
309 if( frequencies
[ i
] > argument
)
311 if( ( argument
- frequencies
[ i
- 1 ] ) <
312 ( frequencies
[ i
] - argument
) )
323 return 0; // Will not happen
326 return (IPTR
) "Martin 'Leviticus' Blom";
328 case AHIDB_Copyright
:
329 return (IPTR
) "Public Domain";
332 return (IPTR
) LibIDString
;
338 return TRUE
; // This is not actually true
344 return (IPTR
) "Void"; // We have only one "output"!
352 /******************************************************************************
353 ** AHIsub_HardwareControl *****************************************************
354 ******************************************************************************/
357 _AHIsub_HardwareControl( ULONG attribute
,
359 struct AHIAudioCtrlDrv
* AudioCtrl
,
360 struct DriverBase
* AHIsubBase
)