3 * This is a driver for hosted AROS, using oss.library.
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"
25 PROCGW( static, void, slaveentry
, SlaveEntry
);
28 /* Since I have no idea what frequencies OSS supports, and there
29 * doesn't seem to be an easy way to find out either, I've just
30 * selected a few common frequencies that are likely to work.
33 static const LONG frequencies
[] =
35 8000, // ยต- and A-Law (telephone)
42 #define FREQUENCIES (sizeof frequencies / sizeof frequencies[ 0 ])
44 /******************************************************************************
45 ** AHIsub_AllocAudio **********************************************************
46 ******************************************************************************/
49 _AHIsub_AllocAudio( struct TagItem
* taglist
,
50 struct AHIAudioCtrlDrv
* AudioCtrl
,
51 struct DriverBase
* AHIsubBase
)
53 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
54 int freq
= AudioCtrl
->ahiac_MixFreq
;
56 AudioCtrl
->ahiac_DriverData
= AllocVec( sizeof( struct AROSData
),
57 MEMF_CLEAR
| MEMF_PUBLIC
);
59 #define dd ((struct AROSData*) AudioCtrl->ahiac_DriverData)
64 dd
->mastersignal
= AllocSignal( -1 );
65 dd
->mastertask
= (struct Process
*) FindTask( NULL
);
66 dd
->ahisubbase
= AROSBase
;
73 if( dd
->mastersignal
== -1 )
78 if( ! OSS_Open( "/dev/dsp", FALSE
, TRUE
, FALSE
) )
83 // 32 fragments times 256 bytes each
85 if( ! OSS_SetFragmentSize( 32, 8 ) )
87 Req( "OSS device does not support a fragment size of 1024." );
91 if( ! OSS_FormatSupported_S16LE() || ! OSS_SetFormat_S16LE() )
93 Req( "OSS device does not support 16 bit little endian samples!" );
97 if( ! OSS_SetWriteRate( freq
, &freq
) )
99 Req( "OSS device does not support the requested frequency." );
103 AudioCtrl
->ahiac_MixFreq
= freq
;
105 return ( AHISF_KNOWHIFI
|
112 /******************************************************************************
113 ** AHIsub_FreeAudio ***********************************************************
114 ******************************************************************************/
117 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
118 struct DriverBase
* AHIsubBase
)
120 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
122 if( AudioCtrl
->ahiac_DriverData
!= NULL
)
126 FreeSignal( dd
->mastersignal
);
127 FreeVec( AudioCtrl
->ahiac_DriverData
);
128 AudioCtrl
->ahiac_DriverData
= NULL
;
133 /******************************************************************************
134 ** AHIsub_Disable *************************************************************
135 ******************************************************************************/
138 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
139 struct DriverBase
* AHIsubBase
)
141 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
143 // V6 drivers do not have to preserve all registers
149 /******************************************************************************
150 ** AHIsub_Enable **************************************************************
151 ******************************************************************************/
154 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
155 struct DriverBase
* AHIsubBase
)
157 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
159 // V6 drivers do not have to preserve all registers
165 /******************************************************************************
166 ** AHIsub_Start ***************************************************************
167 ******************************************************************************/
170 _AHIsub_Start( ULONG flags
,
171 struct AHIAudioCtrlDrv
* AudioCtrl
,
172 struct DriverBase
* AHIsubBase
)
174 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
176 AHIsub_Stop( flags
, AudioCtrl
);
178 if(flags
& AHISF_PLAY
)
180 int freq
= AudioCtrl
->ahiac_MixFreq
;
182 struct TagItem proctags
[] =
184 { NP_Entry
, (IPTR
) &slaveentry
},
185 { NP_Name
, (IPTR
) LibName
},
186 { NP_Priority
, 127 },
191 dd
->mixbuffer
= AllocVec( AudioCtrl
->ahiac_BuffSize
,
192 MEMF_ANY
| MEMF_PUBLIC
);
194 if( dd
->mixbuffer
== NULL
) return AHIE_NOMEM
;
198 dd
->slavetask
= CreateNewProc( proctags
);
200 if( dd
->slavetask
!= NULL
)
202 dd
->slavetask
->pr_Task
.tc_UserData
= AudioCtrl
;
207 if( dd
->slavetask
!= NULL
)
209 Wait( 1L << dd
->mastersignal
); // Wait for slave to come alive
211 if( dd
->slavetask
== NULL
) // Is slave alive or dead?
218 return AHIE_NOMEM
; // Well, out of memory or whatever...
221 // Since OSS kind of sucks, we have to close and reopen it here ...
223 Forbid(); /* To prevent slave task from calling OSS_GetOutputInfo
224 inbetween OSS_Open/OSS_Close */
227 if( ! OSS_Open( "/dev/dsp", FALSE
, TRUE
, FALSE
) )
229 Req( "OSS device would not reopen." );
234 // 32 fragments times 256 bytes each
236 if( ! OSS_SetFragmentSize( 32, 8 ) )
238 Req( "OSS device does not support a fragment size of 1024." );
242 switch( AudioCtrl
->ahiac_BuffType
)
246 if( ! OSS_SetMono() )
248 Req( "OSS device does not support mono samples." );
255 if( ! OSS_SetStereo() )
257 Req( "OSS device does not support stereo samples." );
263 Req( "Unknown sample format requested: %08lx",
264 AudioCtrl
->ahiac_BuffType
);
268 if( ! OSS_SetFormat_S16LE() )
270 Req( "OSS device does not support 16 bit little endian samples!" );
274 if( ! OSS_SetWriteRate( freq
, &freq
) )
276 Req( "OSS device does not support the requested frequency." );
281 if( flags
& AHISF_RECORD
)
290 /******************************************************************************
291 ** AHIsub_Update **************************************************************
292 ******************************************************************************/
295 _AHIsub_Update( ULONG flags
,
296 struct AHIAudioCtrlDrv
* AudioCtrl
,
297 struct DriverBase
* AHIsubBase
)
299 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
305 /******************************************************************************
306 ** AHIsub_Stop ****************************************************************
307 ******************************************************************************/
310 _AHIsub_Stop( ULONG flags
,
311 struct AHIAudioCtrlDrv
* AudioCtrl
,
312 struct DriverBase
* AHIsubBase
)
314 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
316 if( flags
& AHISF_PLAY
)
318 if( dd
->slavetask
!= NULL
)
320 if( dd
->slavesignal
!= -1 )
322 Signal( (struct Task
*) dd
->slavetask
,
323 1L << dd
->slavesignal
); // Kill him!
326 Wait( 1L << dd
->mastersignal
); // Wait for slave to die
329 FreeVec( dd
->mixbuffer
);
330 dd
->mixbuffer
= NULL
;
333 if(flags
& AHISF_RECORD
)
340 /******************************************************************************
341 ** AHIsub_GetAttr *************************************************************
342 ******************************************************************************/
345 _AHIsub_GetAttr( ULONG attribute
,
348 struct TagItem
* taglist
,
349 struct AHIAudioCtrlDrv
* AudioCtrl
,
350 struct DriverBase
* AHIsubBase
)
352 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;
360 case AHIDB_Frequencies
:
363 case AHIDB_Frequency
: // Index->Frequency
364 return (LONG
) frequencies
[ argument
];
366 case AHIDB_Index
: // Frequency->Index
367 if( argument
<= frequencies
[ 0 ] )
372 if( argument
>= frequencies
[ FREQUENCIES
- 1 ] )
374 return FREQUENCIES
- 1;
377 for( i
= 1; i
< FREQUENCIES
; i
++ )
379 if( frequencies
[ i
] > argument
)
381 if( ( argument
- frequencies
[ i
- 1 ] ) <
382 ( frequencies
[ i
] - argument
) )
393 return 0; // Will not happen
396 return (IPTR
) "Martin 'Leviticus' Blom";
398 case AHIDB_Copyright
:
399 return (IPTR
) "Public Domain";
402 return (IPTR
) LibIDString
;
414 return (IPTR
) "AROS"; // We have only one "output"!
422 /******************************************************************************
423 ** AHIsub_HardwareControl *****************************************************
424 ******************************************************************************/
427 _AHIsub_HardwareControl( ULONG attribute
,
429 struct AHIAudioCtrlDrv
* AudioCtrl
,
430 struct DriverBase
* AHIsubBase
)
432 struct AROSBase
* AROSBase
= (struct AROSBase
*) AHIsubBase
;