5 #include <devices/ahi.h>
7 #include <dos/dostags.h>
8 #include <graphics/gfxbase.h>
9 #include <libraries/ahi_sub.h>
10 #include <libraries/asl.h>
11 #include <datatypes/datatypes.h>
13 #include <proto/asl.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/intuition.h>
17 #include <proto/utility.h>
18 #include <proto/datatypes.h>
19 #include <proto/ahi_sub.h>
22 #include "DriverData.h"
23 #include "FileFormats.h"
26 #define dd ((struct FilesaveData*) AudioCtrl->ahiac_DriverData)
28 void PlaySlaveEntry(void);
29 void RecSlaveEntry(void);
31 PROCGW( static, void, playslaveentry
, PlaySlaveEntry
);
32 PROCGW( static, void, recslaveentry
, RecSlaveEntry
);
34 static const LONG frequency
[] =
38 8000, // ยต- and A-Law
54 44056, // Some kind of video rate
61 #define FREQUENCIES (sizeof frequency / sizeof frequency[ 0 ])
64 /******************************************************************************
65 ** AHIsub_AllocAudio **********************************************************
66 ******************************************************************************/
68 ULONG
_AHIsub_AllocAudio(
69 struct TagItem
*tagList
,
70 struct AHIAudioCtrlDrv
*AudioCtrl
,
71 struct DriverBase
* AHIsubBase
)
73 struct FilesaveBase
* FilesaveBase
= (struct FilesaveBase
*) AHIsubBase
;
81 AudioCtrl
->ahiac_DriverData
= AllocVec(sizeof(struct FilesaveData
),MEMF_CLEAR
);
85 dd
->fs_AHIsubBase
= AHIsubBase
;
86 dd
->fs_SlaveSignal
= -1;
87 dd
->fs_MasterSignal
= AllocSignal(-1);
88 dd
->fs_MasterTask
= (struct Process
*) FindTask(NULL
);
89 dd
->fs_RecSlaveSignal
= -1;
90 dd
->fs_RecMasterSignal
= AllocSignal(-1);
97 if((dd
->fs_MasterSignal
== -1) || (dd
->fs_RecMasterSignal
== -1))
102 dd
->fs_Format
= GetTagData(AHIDB_FileSaveFormat
, FORMAT_8SVX
, tagList
);
104 switch(dd
->fs_Format
)
130 struct TagItem playtags
[] =
132 { ASLFR_InitialFile
, (ULONG
) ext
},
133 { ASLFR_DoSaveMode
, TRUE
},
134 { ASLFR_RejectIcons
, TRUE
},
135 { ASLFR_TitleText
, (ULONG
) LibName
},
139 struct TagItem rectags
[] =
141 { ASLFR_RejectIcons
, TRUE
},
142 { ASLFR_TitleText
, (ULONG
) "Select a sound sample" },
146 if(!(dd
->fs_FileReq
= AllocAslRequest(ASL_FileRequest
, playtags
)))
151 if(!(dd
->fs_RecFileReq
= AllocAslRequest(ASL_FileRequest
, rectags
)))
157 return AHISF_KNOWHIFI
|AHISF_KNOWSTEREO
|AHISF_CANRECORD
|AHISF_MIXING
|AHISF_TIMING
;
161 /******************************************************************************
162 ** AHIsub_FreeAudio ***********************************************************
163 ******************************************************************************/
165 void _AHIsub_FreeAudio(
166 struct AHIAudioCtrlDrv
*AudioCtrl
,
167 struct DriverBase
* AHIsubBase
)
170 struct FilesaveBase
* FilesaveBase
= (struct FilesaveBase
*) AHIsubBase
;
172 if(AudioCtrl
->ahiac_DriverData
)
174 FreeAslRequest(dd
->fs_FileReq
);
175 FreeAslRequest(dd
->fs_RecFileReq
);
176 FreeSignal(dd
->fs_MasterSignal
);
177 FreeSignal(dd
->fs_RecMasterSignal
);
178 FreeVec(AudioCtrl
->ahiac_DriverData
);
179 AudioCtrl
->ahiac_DriverData
= NULL
;
183 /******************************************************************************
184 ** AHIsub_Disable *************************************************************
185 ******************************************************************************/
188 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
189 struct DriverBase
* AHIsubBase
)
191 // V6 drivers do not have to preserve all registers
197 /******************************************************************************
198 ** AHIsub_Enable **************************************************************
199 ******************************************************************************/
202 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
203 struct DriverBase
* AHIsubBase
)
205 // V6 drivers do not have to preserve all registers
211 /******************************************************************************
212 ** AHIsub_Start ***************************************************************
213 ******************************************************************************/
217 struct AHIAudioCtrlDrv
*AudioCtrl
,
218 struct DriverBase
* AHIsubBase
)
220 struct FilesaveBase
* FilesaveBase
= (struct FilesaveBase
*) AHIsubBase
;
222 AHIsub_Stop(Flags
, AudioCtrl
);
224 if(Flags
& AHISF_PLAY
)
226 ULONG savebufferlength
;
228 if(!(dd
->fs_MixBuffer
= AllocVec(AudioCtrl
->ahiac_BuffSize
, MEMF_ANY
)))
231 dd
->fs_SaveBufferSize
= AudioCtrl
->ahiac_MaxBuffSamples
;
233 // S16 has two buffers (L/R) instead
234 if((AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
) && dd
->fs_Format
!= FORMAT_S16
)
236 dd
->fs_SaveBufferSize
<<=1;
239 if(dd
->fs_SaveBufferSize
< SAVEBUFFERSIZE
)
241 dd
->fs_SaveBufferSize
= SAVEBUFFERSIZE
;
244 savebufferlength
= dd
->fs_SaveBufferSize
;
247 switch(dd
->fs_Format
)
253 savebufferlength
<<= 1;
257 savebufferlength
<<= 1;
261 savebufferlength
<<= 1;
265 savebufferlength
<<= 1;
273 if(!(dd
->fs_SaveBuffer
= AllocVec(savebufferlength
, MEMF_ANY
)))
278 if ((AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
) && dd
->fs_Format
== FORMAT_S16
)
280 if(!(dd
->fs_SaveBuffer2
= AllocVec(savebufferlength
, MEMF_ANY
)))
286 if(AslRequest(dd
->fs_FileReq
,NULL
))
288 struct TagItem proctags
[] =
290 { NP_Entry
, (IPTR
) &playslaveentry
},
291 { NP_Name
, (IPTR
) LibName
},
292 { NP_Priority
, -1 }, // It's a number cruncher...
293 { NP_StackSize
, 10000, },
299 dd
->fs_SlaveTask
= CreateNewProc( proctags
);
301 if( dd
->fs_SlaveTask
!= NULL
)
303 dd
->fs_SlaveTask
->pr_Task
.tc_UserData
= AudioCtrl
;
310 Wait(1L<<dd
->fs_MasterSignal
); // Wait for slave to come alive
311 if(dd
->fs_SlaveTask
== NULL
) // Is slave alive or dead?
325 return AHIE_NOMEM
; //error occured
329 return AHIE_ABORTED
; //requester cancelled
334 if(Flags
& AHISF_RECORD
)
336 if(!(dd
->fs_RecBuffer
= AllocVec(RECBUFFERSIZE
*4,MEMF_ANY
)))
341 if(AslRequest(dd
->fs_RecFileReq
,NULL
))
343 struct TagItem proctags
[] =
345 { NP_Entry
, (ULONG
) &recslaveentry
},
346 { NP_Name
, (ULONG
) LibName
},
347 { NP_Priority
, 1 }, // Make it steady...
351 Delay(TICKS_PER_SECOND
); // Wait for window to close etc...
355 dd
->fs_RecSlaveTask
= CreateNewProc( proctags
);
357 if( dd
->fs_RecSlaveTask
!= NULL
)
359 dd
->fs_RecSlaveTask
->pr_Task
.tc_UserData
= AudioCtrl
;
364 if(dd
->fs_RecSlaveTask
)
366 Wait(1L<<dd
->fs_RecMasterSignal
); // Wait for slave to come alive
367 if(dd
->fs_RecSlaveTask
== NULL
) // Is slave alive or dead?
381 return AHIE_NOMEM
; //error occured
385 return AHIE_ABORTED
; //requester cancelled
394 /******************************************************************************
395 ** AHIsub_Update **************************************************************
396 ******************************************************************************/
400 struct AHIAudioCtrlDrv
*AudioCtrl
,
401 struct DriverBase
* AHIsubBase
)
406 /******************************************************************************
407 ** AHIsub_Stop ****************************************************************
408 ******************************************************************************/
412 struct AHIAudioCtrlDrv
*AudioCtrl
,
413 struct DriverBase
* AHIsubBase
)
415 if(Flags
& AHISF_PLAY
)
419 if(dd
->fs_SlaveSignal
!= -1)
421 Signal((struct Task
*)dd
->fs_SlaveTask
,1L<<dd
->fs_SlaveSignal
); // Kill him!
423 Wait(1L<<dd
->fs_MasterSignal
); // Wait for slave to die
425 FreeVec(dd
->fs_MixBuffer
);
426 dd
->fs_MixBuffer
= NULL
;
427 FreeVec(dd
->fs_SaveBuffer
);
428 FreeVec(dd
->fs_SaveBuffer2
);
429 dd
->fs_SaveBuffer
= NULL
;
430 dd
->fs_SaveBuffer2
= NULL
;
433 if(Flags
& AHISF_RECORD
)
435 if(dd
->fs_RecSlaveTask
)
437 if(dd
->fs_RecSlaveSignal
!= -1)
439 Signal((struct Task
*)dd
->fs_RecSlaveTask
,1L<<dd
->fs_RecSlaveSignal
); // Kill him!
441 Wait(1L<<dd
->fs_RecMasterSignal
); // Wait for slave to die
443 FreeVec(dd
->fs_RecBuffer
);
444 dd
->fs_RecBuffer
= NULL
;
449 /******************************************************************************
450 ** AHIsub_GetAttr *************************************************************
451 ******************************************************************************/
453 IPTR
_AHIsub_GetAttr(
457 struct TagItem
*tagList
,
458 struct AHIAudioCtrlDrv
*AudioCtrl
,
459 struct DriverBase
* AHIsubBase
)
466 switch (GetTagData(AHIDB_FileSaveFormat
,FORMAT_8SVX
,tagList
))
487 case AHIDB_Frequencies
:
490 case AHIDB_Frequency
: // Index->Frequency
491 return (LONG
) frequency
[Argument
];
493 case AHIDB_Index
: // Frequency->Index
494 if(Argument
<= frequency
[0])
498 if(Argument
>= frequency
[FREQUENCIES
-1])
500 return FREQUENCIES
-1;
502 for(i
= 1;i
<FREQUENCIES
;i
++)
504 if(frequency
[i
]>Argument
)
506 if( (Argument
-frequency
[i
-1]) < (frequency
[i
]-Argument
) )
516 return 0; // Will not happen
519 return (IPTR
) "Martin 'Leviticus' Blom";
521 case AHIDB_Copyright
:
522 return (IPTR
) "Public Domain";
525 return (IPTR
) LibIDString
;
530 case AHIDB_FullDuplex
:
533 case AHIDB_MaxRecordSamples
:
534 return RECBUFFERSIZE
;
543 return (IPTR
) "File"; // We have only one input!
549 return (IPTR
) "File"; // We have only one output!
557 /******************************************************************************
558 ** AHIsub_HardwareControl *****************************************************
559 ******************************************************************************/
561 ULONG
_AHIsub_HardwareControl(
564 struct AHIAudioCtrlDrv
*AudioCtrl
,
565 struct DriverBase
* AHIsubBase
)