Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / Filesave / filesave-main.c
blobe410c06223573e3cbe06505af8d96917ba137a7a
2 #include <config.h>
4 #include <exec/exec.h>
5 #include <devices/ahi.h>
6 #include <dos/dos.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>
20 #include <stdlib.h>
22 #include "DriverData.h"
23 #include "FileFormats.h"
24 #include "library.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[] =
36 5513,
37 6615,
38 8000, // ยต- and A-Law
39 9600, // DAT/5
40 11025, // CD/4
41 12000, // DAT/4
42 14700, // CD/3
43 16000, // DAT/3
44 17640, // CD/2.5
45 18900,
46 19200, // DAT/2.5
47 22050, // CD/2
48 24000, // DAT/2
49 27429,
50 29400, // CD/1.5
51 32000, // DAT/1.5
52 33075,
53 37800,
54 44056, // Some kind of video rate
55 44100, // CD
56 48000, // DAT
57 88200, // CD*2
58 96000 // DAT*2
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;
74 char *ext = "";
76 if(AslBase == NULL)
78 return AHISF_ERROR;
81 AudioCtrl->ahiac_DriverData = AllocVec(sizeof(struct FilesaveData),MEMF_CLEAR);
83 if( dd != NULL )
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);
92 else
94 return AHISF_ERROR;
97 if((dd->fs_MasterSignal == -1) || (dd->fs_RecMasterSignal == -1))
99 return AHISF_ERROR;
102 dd->fs_Format = GetTagData(AHIDB_FileSaveFormat, FORMAT_8SVX, tagList);
104 switch(dd->fs_Format)
106 case FORMAT_8SVX:
107 ext = ".8SVX";
108 break;
110 case FORMAT_AIFF:
111 ext = ".AIFF";
112 break;
114 case FORMAT_AIFC:
115 ext = ".AIFC";
116 break;
118 case FORMAT_S16:
119 break;
121 case FORMAT_WAVE:
122 ext = ".WAV";
123 break;
125 default:
126 break;
130 struct TagItem playtags[] =
132 { ASLFR_InitialFile, (ULONG) ext },
133 { ASLFR_DoSaveMode, TRUE },
134 { ASLFR_RejectIcons, TRUE },
135 { ASLFR_TitleText, (ULONG) LibName },
136 { TAG_DONE, 0 }
139 struct TagItem rectags[] =
141 { ASLFR_RejectIcons, TRUE },
142 { ASLFR_TitleText, (ULONG) "Select a sound sample" },
143 { TAG_DONE, 0 }
146 if(!(dd->fs_FileReq = AllocAslRequest(ASL_FileRequest, playtags)))
148 return AHISF_ERROR;
151 if(!(dd->fs_RecFileReq = AllocAslRequest(ASL_FileRequest, rectags)))
153 return AHISF_ERROR;
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 ******************************************************************************/
187 void
188 _AHIsub_Disable( struct AHIAudioCtrlDrv* AudioCtrl,
189 struct DriverBase* AHIsubBase )
191 // V6 drivers do not have to preserve all registers
193 Forbid();
197 /******************************************************************************
198 ** AHIsub_Enable **************************************************************
199 ******************************************************************************/
201 void
202 _AHIsub_Enable( struct AHIAudioCtrlDrv* AudioCtrl,
203 struct DriverBase* AHIsubBase )
205 // V6 drivers do not have to preserve all registers
207 Permit();
211 /******************************************************************************
212 ** AHIsub_Start ***************************************************************
213 ******************************************************************************/
215 ULONG _AHIsub_Start(
216 ULONG Flags,
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)))
229 return AHIE_NOMEM;
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)
249 case FORMAT_8SVX:
250 break;
252 case FORMAT_AIFF:
253 savebufferlength <<= 1;
254 break;
256 case FORMAT_AIFC:
257 savebufferlength <<= 1;
258 break;
260 case FORMAT_S16:
261 savebufferlength <<= 1;
262 break;
264 case FORMAT_WAVE:
265 savebufferlength <<= 1;
266 break;
268 default:
269 break;
273 if(!(dd->fs_SaveBuffer = AllocVec(savebufferlength, MEMF_ANY)))
275 return AHIE_NOMEM;
278 if ((AudioCtrl->ahiac_Flags & AHIACF_STEREO) && dd->fs_Format == FORMAT_S16)
280 if(!(dd->fs_SaveBuffer2 = AllocVec(savebufferlength, MEMF_ANY)))
282 return AHIE_NOMEM;
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, },
294 { TAG_DONE, 0 }
297 Forbid();
299 dd->fs_SlaveTask = CreateNewProc( proctags );
301 if( dd->fs_SlaveTask != NULL )
303 dd->fs_SlaveTask->pr_Task.tc_UserData = AudioCtrl;
306 Permit();
308 if(dd->fs_SlaveTask)
310 Wait(1L<<dd->fs_MasterSignal); // Wait for slave to come alive
311 if(dd->fs_SlaveTask == NULL) // Is slave alive or dead?
313 return AHIE_UNKNOWN;
316 else
318 return AHIE_NOMEM;
321 else
323 if(IoErr())
325 return AHIE_NOMEM; //error occured
327 else
329 return AHIE_ABORTED; //requester cancelled
334 if(Flags & AHISF_RECORD)
336 if(!(dd->fs_RecBuffer = AllocVec(RECBUFFERSIZE*4,MEMF_ANY)))
338 return AHIE_NOMEM;
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...
348 { TAG_DONE, 0 }
351 Delay(TICKS_PER_SECOND); // Wait for window to close etc...
353 Forbid();
355 dd->fs_RecSlaveTask = CreateNewProc( proctags );
357 if( dd->fs_RecSlaveTask != NULL )
359 dd->fs_RecSlaveTask->pr_Task.tc_UserData = AudioCtrl;
362 Permit();
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?
369 return AHIE_UNKNOWN;
372 else
374 return AHIE_NOMEM;
377 else
379 if(IoErr())
381 return AHIE_NOMEM; //error occured
383 else
385 return AHIE_ABORTED; //requester cancelled
390 return AHIE_OK;
394 /******************************************************************************
395 ** AHIsub_Update **************************************************************
396 ******************************************************************************/
398 void _AHIsub_Update(
399 ULONG Flags,
400 struct AHIAudioCtrlDrv *AudioCtrl,
401 struct DriverBase* AHIsubBase )
406 /******************************************************************************
407 ** AHIsub_Stop ****************************************************************
408 ******************************************************************************/
410 void _AHIsub_Stop(
411 ULONG Flags,
412 struct AHIAudioCtrlDrv *AudioCtrl,
413 struct DriverBase* AHIsubBase )
415 if(Flags & AHISF_PLAY)
417 if(dd->fs_SlaveTask)
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(
454 ULONG Attribute,
455 LONG Argument,
456 IPTR Default,
457 struct TagItem *tagList,
458 struct AHIAudioCtrlDrv *AudioCtrl,
459 struct DriverBase* AHIsubBase )
461 size_t i;
463 switch(Attribute)
465 case AHIDB_Bits:
466 switch (GetTagData(AHIDB_FileSaveFormat,FORMAT_8SVX,tagList))
468 case FORMAT_8SVX:
469 return 8;
471 case FORMAT_AIFF:
472 return 16;
474 case FORMAT_AIFC:
475 return 16;
477 case FORMAT_S16:
478 return 16;
480 case FORMAT_WAVE:
481 return 16;
483 default:
484 return Default;
487 case AHIDB_Frequencies:
488 return FREQUENCIES;
490 case AHIDB_Frequency: // Index->Frequency
491 return (LONG) frequency[Argument];
493 case AHIDB_Index: // Frequency->Index
494 if(Argument <= frequency[0])
496 return 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) )
508 return i-1;
510 else
512 return i;
516 return 0; // Will not happen
518 case AHIDB_Author:
519 return (IPTR) "Martin 'Leviticus' Blom";
521 case AHIDB_Copyright:
522 return (IPTR) "Public Domain";
524 case AHIDB_Version:
525 return (IPTR) LibIDString;
527 case AHIDB_Record:
528 return TRUE;
530 case AHIDB_FullDuplex:
531 return TRUE;
533 case AHIDB_MaxRecordSamples:
534 return RECBUFFERSIZE;
536 case AHIDB_Realtime:
537 return FALSE;
539 case AHIDB_Inputs:
540 return 1;
542 case AHIDB_Input:
543 return (IPTR) "File"; // We have only one input!
545 case AHIDB_Outputs:
546 return 1;
548 case AHIDB_Output:
549 return (IPTR) "File"; // We have only one output!
551 default:
552 return Default;
557 /******************************************************************************
558 ** AHIsub_HardwareControl *****************************************************
559 ******************************************************************************/
561 ULONG _AHIsub_HardwareControl(
562 ULONG attribute,
563 LONG argument,
564 struct AHIAudioCtrlDrv *AudioCtrl,
565 struct DriverBase* AHIsubBase )
567 return 0;