3 #include <devices/ahi.h>
4 #include <dos/dostags.h>
5 #include <exec/memory.h>
6 #include <libraries/ahi_sub.h>
7 #include <proto/ahi_sub.h>
8 #include <proto/exec.h>
10 #include <proto/utility.h>
15 #include "DriverData.h"
17 #define dd ((struct AlsaData*) AudioCtrl->ahiac_DriverData)
22 PROCGW( static, void, slaveentry
, SlaveEntry
);
26 /* There is probably no reason to support all these frequencies. If,
27 * for example, your hardware is locked at 48 kHz, it's ok to only
28 * present one single mixing/recording frequency to the user. If your
29 * hardware has internal resamples and accept any frequency, select a
33 static const LONG frequencies
[] =
36 8000, // ยต- and A-Law (telephone)
38 10000, // VHS monaural track
46 20000, // VHS Hi-Fi/Video track
49 27429, // Highest Paula/OCS frequency
51 31968, // NTSC FM 2-3 pull-down
53 32032, // NTSC FM 2-3 pull-up
56 44056, // NTSC CD 2-3 pull-down
58 44144, // NTSC CD 2-3 pull-up
59 47952, // NTSC DAT 2-3 pull-down
61 48048, // NTSC DAT 2-3 pull-up
66 #define FREQUENCIES (sizeof frequencies / sizeof frequencies[ 0 ])
68 /******************************************************************************
69 ** AHIsub_AllocAudio **********************************************************
70 ******************************************************************************/
73 _AHIsub_AllocAudio( struct TagItem
* taglist
,
74 struct AHIAudioCtrlDrv
* AudioCtrl
,
75 struct DriverBase
* AHIsubBase
)
77 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
78 ULONG freq
= AudioCtrl
->ahiac_MixFreq
;
80 AudioCtrl
->ahiac_DriverData
= AllocVec( sizeof( struct AlsaData
),
81 MEMF_CLEAR
| MEMF_PUBLIC
);
86 dd
->mastersignal
= AllocSignal( -1 );
87 dd
->mastertask
= (struct Process
*) FindTask( NULL
);
88 dd
->ahisubbase
= AlsaBase
;
95 if( dd
->mastersignal
== -1 )
100 dd
->alsahandle
= ALSA_Open();
102 if (dd
->alsahandle
== NULL
)
107 if (!ALSA_SetHWParams(dd
->alsahandle
, &freq
))
109 ALSA_Close(dd
->alsahandle
);
110 dd
->alsahandle
= NULL
;
114 AudioCtrl
->ahiac_MixFreq
= freq
;
116 return ( AHISF_KNOWSTEREO
| AHISF_MIXING
| AHISF_TIMING
);
120 /******************************************************************************
121 ** AHIsub_FreeAudio ***********************************************************
122 ******************************************************************************/
125 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
126 struct DriverBase
* AHIsubBase
)
128 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
130 if( AudioCtrl
->ahiac_DriverData
!= NULL
)
132 ALSA_Close(dd
->alsahandle
);
133 FreeSignal( dd
->mastersignal
);
134 FreeVec( AudioCtrl
->ahiac_DriverData
);
135 AudioCtrl
->ahiac_DriverData
= NULL
;
140 /******************************************************************************
141 ** AHIsub_Disable *************************************************************
142 ******************************************************************************/
145 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
146 struct DriverBase
* AHIsubBase
)
148 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
150 // V6 drivers do not have to preserve all registers
156 /******************************************************************************
157 ** AHIsub_Enable **************************************************************
158 ******************************************************************************/
161 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
162 struct DriverBase
* AHIsubBase
)
164 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
166 // V6 drivers do not have to preserve all registers
172 /******************************************************************************
173 ** AHIsub_Start ***************************************************************
174 ******************************************************************************/
177 _AHIsub_Start( ULONG flags
,
178 struct AHIAudioCtrlDrv
* AudioCtrl
,
179 struct DriverBase
* AHIsubBase
)
181 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
183 AHIsub_Stop( flags
, AudioCtrl
);
185 if(flags
& AHISF_PLAY
)
187 struct TagItem proctags
[] =
189 { NP_Entry
, (IPTR
) &slaveentry
},
190 { NP_Name
, (IPTR
) LibName
},
191 { NP_Priority
, 127 },
195 dd
->mixbuffer
= AllocVec( AudioCtrl
->ahiac_BuffSize
,
196 MEMF_ANY
| MEMF_PUBLIC
);
198 if( dd
->mixbuffer
== NULL
) return AHIE_NOMEM
;
202 dd
->slavetask
= CreateNewProc( proctags
);
204 if( dd
->slavetask
!= NULL
)
206 dd
->slavetask
->pr_Task
.tc_UserData
= AudioCtrl
;
211 if( dd
->slavetask
!= NULL
)
213 Wait( 1L << dd
->mastersignal
); // Wait for slave to come alive
215 if( dd
->slavetask
== NULL
) // Is slave alive or dead?
222 return AHIE_NOMEM
; // Well, out of memory or whatever...
226 if( flags
& AHISF_RECORD
)
235 /******************************************************************************
236 ** AHIsub_Update **************************************************************
237 ******************************************************************************/
240 _AHIsub_Update( ULONG flags
,
241 struct AHIAudioCtrlDrv
* AudioCtrl
,
242 struct DriverBase
* AHIsubBase
)
244 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
250 /******************************************************************************
251 ** AHIsub_Stop ****************************************************************
252 ******************************************************************************/
255 _AHIsub_Stop( ULONG flags
,
256 struct AHIAudioCtrlDrv
* AudioCtrl
,
257 struct DriverBase
* AHIsubBase
)
259 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
261 if( flags
& AHISF_PLAY
)
263 if( dd
->slavetask
!= NULL
)
265 if( dd
->slavesignal
!= -1 )
267 Signal( (struct Task
*) dd
->slavetask
,
268 1L << dd
->slavesignal
); // Kill him!
271 Wait( 1L << dd
->mastersignal
); // Wait for slave to die
274 FreeVec( dd
->mixbuffer
);
275 dd
->mixbuffer
= NULL
;
278 if(flags
& AHISF_RECORD
)
285 /******************************************************************************
286 ** AHIsub_GetAttr *************************************************************
287 ******************************************************************************/
290 _AHIsub_GetAttr( ULONG attribute
,
293 struct TagItem
* taglist
,
294 struct AHIAudioCtrlDrv
* AudioCtrl
,
295 struct DriverBase
* AHIsubBase
)
297 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;
305 case AHIDB_Frequencies
:
308 case AHIDB_Frequency
: // Index->Frequency
309 return (LONG
) frequencies
[ argument
];
311 case AHIDB_Index
: // Frequency->Index
312 if( argument
<= frequencies
[ 0 ] )
317 if( argument
>= frequencies
[ FREQUENCIES
- 1 ] )
319 return FREQUENCIES
- 1;
322 for( i
= 1; i
< FREQUENCIES
; i
++ )
324 if( frequencies
[ i
] > argument
)
326 if( ( argument
- frequencies
[ i
- 1 ] ) <
327 ( frequencies
[ i
] - argument
) )
338 return 0; // Will not happen
341 return (IPTR
) "Krzysztof Smiechowicz";
343 case AHIDB_Copyright
:
347 return (IPTR
) LibIDString
;
359 return (IPTR
) "Alsa"; // We have only one "output"!
367 /******************************************************************************
368 ** AHIsub_HardwareControl *****************************************************
369 ******************************************************************************/
372 _AHIsub_HardwareControl( ULONG attribute
,
374 struct AHIAudioCtrlDrv
* AudioCtrl
,
375 struct DriverBase
* AHIsubBase
)
377 struct AlsaBase
* AlsaBase
= (struct AlsaBase
*) AHIsubBase
;