Port the SB128 code to AROS.
[AROS.git] / workbench / devs / audio / audio_commands.c
blob4d693fdb3a96331510b8ff51967c4d47379667cc
1 /*
2 Copyright 2010, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * audio.device
9 * by Nexus Development 2003
10 * coded by Emanuele Cesaroni
12 * $Id$
15 #include "audio_intern.h"
16 #define DEBUG 0
17 #include <aros/debug.h>
18 #include <graphics/gfxbase.h>
21 * In CMD_WRITE when more than one bit is set is considered the lowest this keep fastly it.
23 BYTE writechn[] =
24 { 0, // 0000 - 0 // This combination is bad.
25 0, // 0001 - 1
26 1, // 0010 - 2
27 0, // 0011 - 3
28 2, // 0100 - 4
29 0, // 0101 - 5
30 1, // 0110 - 6
31 0, // 0111 - 7
32 3, // 1000 - 8
33 0, // 1001 - 9
34 1, // 1010 - 10
35 0, // 1011 - 11
36 2, // 1100 - 12
37 0, // 1101 - 13
38 1, // 1110 - 14
39 0 // 1111 - 15
42 VOID setup_Units(UBYTE combination, WORD key, BYTE pri, ETASK *eta)
44 // se sono locked
45 if (combination & (1 << 0))
47 ResetUnit(eta->et_units[0]);
48 eta->et_units[0]->eu_allockey = key;
49 eta->et_units[0]->eu_pri = pri;
50 D(bug("NEWD: Setupped unit %d\n", 0));
53 if (combination & (1 << 1))
55 ResetUnit(eta->et_units[1]);
56 eta->et_units[1]->eu_allockey = key;
57 eta->et_units[1]->eu_pri = pri;
58 D(bug("NEWD: Setupped unit %d\n", 1));
61 if (combination & (1 << 2))
63 ResetUnit(eta->et_units[2]);
64 eta->et_units[2]->eu_allockey = key;
65 eta->et_units[2]->eu_pri = pri;
66 D(bug("NEWD: Setupped unit %d\n", 2));
69 if (combination & (1 << 3))
71 ResetUnit(eta->et_units[3]);
72 eta->et_units[3]->eu_allockey = key;
73 eta->et_units[3]->eu_pri = pri;
74 D(bug("NEWD: Setupped unit %d\n", 3));
77 eta->et_unitmask = combination;
80 VOID AllocateProc(struct IOAudio *audioio, ETASK *eta)
82 BYTE *data, len, actual, pri;
83 WORD key;
84 BOOL result = 0;
86 D(bug("NEWD: Arrived ADCMD_ALLOCATE from IOAudio(%x),len=%d,data=%x,key=%d,pri=%d\n",
87 audioio, audioio->ioa_Length, audioio->ioa_Data, audioio->ioa_AllocKey,
88 audioio->ioa_Request.io_Message.mn_Node.ln_Pri));
90 data = audioio->ioa_Data;
91 pri = audioio->ioa_Request.io_Message.mn_Node.ln_Pri;
93 if ((!(key = audioio->ioa_AllocKey)))
95 key = eta->et_key++; /* Always a new key please. */
98 if ((len = (audioio->ioa_Length & 15))) /* If len is > 0 otherwise is ok so returns unit = 0. */
100 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 // First control search a combination which doesn't subtract any other just allocated.
105 if ((actual = *data++)) /* Actual combination. */
107 D(bug("NEWD: combination %d\n", actual));
108 if ((actual & eta->et_unitmask) == 0)
110 D(bug("NEWD: after combination %d\n", actual));
111 setup_Units(actual, key, pri, eta);
112 audioio->ioa_Request.io_Unit
113 = (struct Unit*) ((IPTR) actual);
114 audioio->ioa_Request.io_Error = IONOERROR;
115 audioio->ioa_AllocKey = key;
117 return; /* EXIT. */
120 else
122 audioio->ioa_Request.io_Unit = (struct Unit*) NULL; /* Lenght is zero but a key is generated, unit is 0 and noerror. */
123 audioio->ioa_Request.io_Error = IONOERROR;
124 audioio->ioa_AllocKey = key;
126 D(bug("NEWD: ADCMD_ALLOCATE asked combination 0\n"));
128 return;
130 } while (--len);
131 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
132 // Nothing... Try now to subtract other channels with lower pri.
134 D(bug("NEWD: I try to subtract\n"));
136 data = audioio->ioa_Data;
137 len = (audioio->ioa_Length & 15);
139 do /* First control search a combination which subtracts a combination with lower pri. */
141 actual = *data++; /* Actual combination. */
143 while (1)
145 if ((actual & (1 << 0)) && (eta->et_unitmask & (1 << 0)))
147 if (eta->et_units[0]->eu_pri >= pri)
148 break;
151 if ((actual & (1 << 1)) && (eta->et_unitmask & (1 << 1)))
153 if (eta->et_units[1]->eu_pri >= pri)
154 break;
157 if ((actual & (1 << 2)) && (eta->et_unitmask & (1 << 2)))
159 if (eta->et_units[2]->eu_pri >= pri)
160 break;
162 if ((actual & (1 << 3)) && (eta->et_unitmask & (1 << 3)))
164 if (eta->et_units[3]->eu_pri >= pri)
165 break;
168 result = 1;
169 break;
172 if (result)
175 Devi semplicemente per i canali sottratti abortire le richieste di CMD_WRITE che giungevano dai task di
176 quelle unit� pagina 126, mettendo in error IOERR_ABORTED. Quelle in esecuzione invece vengono interrotte, quella
177 cached anche ma non viene messo niente in error.
180 setup_Units(actual, key, pri, eta);
181 audioio->ioa_Request.io_Unit = (struct Unit*) ((IPTR) actual);
182 audioio->ioa_Request.io_Error = IONOERROR;
183 audioio->ioa_AllocKey = key;
185 return;
187 } while (--len);
189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
190 // Ok, nothing to do, so or exit or put the IOAudio in waiting state.
192 if (audioio->ioa_Request.io_Flags & ADIOF_NOWAIT)
194 audioio->ioa_Request.io_Unit = (struct Unit*) NULL;
195 audioio->ioa_Request.io_Error = ADIOERR_ALLOCFAILED;
196 D(bug("NEWD: I try to subtract\n"));
198 return;
200 else
202 AddTail(&eta->et_allocatelist,
203 &audioio->ioa_Request.io_Message.mn_Node); /* This now in waiting state */
204 eta->et_allocated++; /* Increase the counter please. */
205 audioio->ioa_Request.io_Flags &= ~IOF_QUICK; /* Try this later. */
206 audioio->ioa_Request.io_Error = ADIOERR_ALLOCFAILED;
207 D(bug("NEWD: ADCMD_ALLOCATE put in waiting allocate list IOAudio '%x'\n",
208 audioio));
210 return;
212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 audioio->ioa_Request.io_Unit = (struct Unit*) NULL; // Lenght is zero but a key is generated, unit is 0 and noerror.
216 audioio->ioa_Request.io_Error = IONOERROR;
217 audioio->ioa_AllocKey = key;
218 D(bug("NEWD: Arrived ADCMD_ALLOCATE with ioa_lenght == 0 IOAudio (%x)\n",
219 audioio));
223 * _ADCMD_ALLOCATE
225 * If the IOAudio can't be processed put the request at the end of the et_allocatelist.
227 * TODO
228 * - What to do when the lenght is > 15 ? Actually this condition is not present because the lenght is anded with 15.
229 * - Do the procedure of removing the cmd_writes when channels are stolens.
230 * - Do the part of reput the request in a list in which must stay waiting for reallocs.
231 * - Pay attention if abortio aborts an ADCMD_ALLOCATE it is removed and the counter of alloc waiting is wrong.
235 VOID _ADCMD_ALLOCATE(struct IOAudio *audioio, ETASK *eta)
237 AllocateProc(audioio, eta);
238 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, STOLEN_SIG);
243 * UnitCopyData
244 * --------------
246 * Copies the data from the audio to the unit fields. This is a pre-cached system as the original audio.device used to do.
250 VOID UnitCopyData(EUNIT *unit, struct IOAudio *audioio)
252 ULONG period;
253 if (audioio->ioa_Length > 131072)
255 unit->eu_len = 131072;
257 else
259 if (audioio->ioa_Length < 2)
261 unit->eu_len = 2;
263 else
265 unit->eu_len = audioio->ioa_Length;
269 if ((period = audioio->ioa_Period) < 124)
270 period = 124;
272 unit->eu_data = audioio->ioa_Data;
273 unit->eu_cycles = audioio->ioa_Cycles;
275 if (audioio->ioa_Request.io_Flags & ADIOF_PERVOL)
277 unit->eu_volume = audioio->ioa_Volume * 1024;
278 //unit->eu_freq = unit->eu_clock / ((ULONG) audioio->ioa_Period);
279 unit->eu_freq = unit->eu_clock / period;
282 unit->eu_audioio = audioio;
283 //audioio->ioa_Request.io_Flags &= ~IOF_QUICK; // This will be outputted surely so treat it as async.
289 * UnitAHIPerVol
290 * ---------------
292 * Do the necessary procedures to change on the fly period and volume into an unit.
296 VOID UnitAHIPerVol(EUNIT *unit, struct IOAudio *audioio)
298 unit->eu_freq = unit->eu_clock / ((ULONG) audioio->ioa_Period);
299 unit->eu_volume = audioio->ioa_Volume * 1024;
303 * UnitInitAhi
304 * -------------
306 * Inits ahi and play the sample.
307 * It removes the data from the precached place as the original audio.device used to do.
311 VOID UnitInitAhi(EUNIT *unit)
313 if (!unit->eu_usingme)
315 unit->eu_ahireq.ahir_Std.io_Data = unit->eu_data;
316 unit->eu_ahireq.ahir_Std.io_Length = unit->eu_len;
317 unit->eu_ahireq.ahir_Frequency = unit->eu_freq;
318 unit->eu_ahireq.ahir_Volume = unit->eu_volume;
319 unit->eu_usingme = unit->eu_audioio;
320 unit->eu_audioio = NULL;
321 unit->eu_savecycles = unit->eu_cycles; // The save value.
322 unit->eu_actcycles = unit->eu_cycles; // The actual counter.
324 if (unit->eu_savecycles != 1) // Save the values for infinite repeating...
326 unit->eu_repdata = unit->eu_data;
327 unit->eu_replen = unit->eu_len;
328 unit->eu_repfreq = unit->eu_freq;
329 unit->eu_repvolume = unit->eu_volume;
332 BeginIO((struct IORequest *) &unit->eu_ahireq);
334 if (unit->eu_usingme->ioa_Request.io_Flags & ADIOF_WRITEMESSAGE)
336 D(bug("NEWD: Reply WRITE_MESSAGE from IOAudio (%x)\n",
337 unit->eu_usingme));
338 ReplyMsg(&unit->eu_usingme->ioa_WriteMsg);
344 * UnitInitRepAhi
345 * ----------------
347 * This is used to reinit ahi when we are under infinite cycles.
350 VOID UnitInitRepAhi(EUNIT *unit)
352 unit->eu_ahireq.ahir_Std.io_Data = unit->eu_repdata;
353 unit->eu_ahireq.ahir_Std.io_Length = unit->eu_replen;
354 unit->eu_ahireq.ahir_Frequency = unit->eu_repfreq;
355 unit->eu_ahireq.ahir_Volume = unit->eu_repvolume;
356 BeginIO((struct IORequest *) &unit->eu_ahireq);
360 * FlushUnit
361 * -----------
363 * Flushes an eaudio.device unit. So:
364 * 1) Aborts the running audio wave.
365 * 2) Get all the CMD_WRITE in list waiting repling them to their task with IOERR_ABORTED.
366 * 3) Returns all the waitcycles in waitcyclelist with IOERR_ABORTED.
368 * ?? The running IOAudio must be replied??
372 VOID FlushUnit(EUNIT *unit)
374 struct IOAudio *audioio;
376 if (!(CheckIO((struct IORequest *) &unit->eu_ahireq))) // I stop if exists the running audio output.
378 AbortIO((struct IORequest *) &unit->eu_ahireq);
379 WaitIO((struct IORequest *) &unit->eu_ahireq);
381 D(bug("NEWD: FlushUnit(): The audio in port (%d) was running now is stopped\n",
382 unit->eu_id));
385 unit->eu_usingme = NULL;
387 while ((audioio = (struct IOAudio*) GetMsg(unit->eu_port))) // Now removes all the CMD_WRITE present in the list.
389 audioio->ioa_Request.io_Error = IOERR_ABORTED;
390 ReplyMsg(&audioio->ioa_Request.io_Message);
392 D(bug("NEWD: FlushUnit(): Removed from the list of port (%d) the CMD_WRITE request (%x).\n",
393 unit->eu_id, audioio));
396 while ((audioio = (struct IOAudio*) RemHead(&unit->eu_waitcyclelist))) // Removes all the ADCMD_WAITCYCLES for this unit.
398 D(bug("NEWD: FlushUnit(): Found IOAuido (%x) in waitcyclelist, now i reply it with IOERR_ABORTED.\n",
399 audioio));
401 audioio->ioa_Request.io_Error = IOERR_ABORTED;
402 ReplyMsg(&audioio->ioa_Request.io_Message);
408 * _CMD_RESET
412 VOID _CMD_RESET(struct IOAudio *audioio, ETASK *eta)
414 BYTE unit, chan, final = 0;
415 EUNIT *channel;
416 UBYTE error = IONOERROR;
418 D(bug("NEWD: Arrived CMD_RESET from IOAudio (%x), unit(%d)\n", audioio,
419 audioio->ioa_Request.io_Unit));
421 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
425 chan = writechn[unit];
426 channel = eta->et_units[chan];
428 if (channel->eu_allockey == audioio->ioa_AllocKey)
430 FlushUnit(channel);
431 D(bug("NEWD: CMD_FLUSH for unit (%d)\n", chan));
433 else
435 error = ADIOERR_NOALLOCATION;
438 unit &= ~(1 << chan);
439 final |= 1 << chan;
440 } while (unit);
443 audioio->ioa_Request.io_Unit = (struct Unit*) ((IPTR) final);
444 audioio->ioa_Request.io_Error = error;
445 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
446 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
450 * ResetUnit
451 * -----------
453 * Does some procedures usefull to reset the unit, Called by CMD_RESET and other.
457 VOID ResetUnit(EUNIT *unit)
459 unit->eu_audioio = NULL; /* This is sufficent to erase the pre-cache requestes. */
460 FlushUnit(unit); /* This stops the running audio and removes all the quequed CMD_WRITE and ADCMD_WAITCYCLES. */
465 * ReAllocateUnits
466 * -----------------
468 * This block try again to ADCMD_ALLOCATE some IOAUdio request which are waiting for channels. Actually it is called from
469 * ADCMD_FREE or ADCMD_SETPREC.
471 * - Pay attention to the counter of the allocate in waiting if an abortio removes it the system collapses !!!!!!!!
475 VOID ReAllocateUnits(ETASK *eta)
477 UWORD allocated;
478 struct IOAudio *wait;
480 if ((allocated = eta->et_allocated)) // If any in list waiting for being allocated.
482 while ((wait = (struct IOAudio*) RemHead(&eta->et_allocatelist)))
484 eta->et_allocated--;
486 D(bug("NEWD: ADCMD_FREE: Trying to allocate this again. IOAudio (%x)\n", wait));
487 AllocateProc(wait, eta);
489 if ((wait->ioa_Request.io_Flags & IOF_QUICK) == 0)
491 if ((wait->ioa_Request.io_Error == ADIOERR_ALLOCFAILED)
492 && (wait->ioa_Request.io_Flags & ADIOF_NOWAIT))
494 ReplyMsg(&wait->ioa_Request.io_Message);
496 else if (wait->ioa_Request.io_Error == IONOERROR)
498 ReplyMsg(&wait->ioa_Request.io_Message);
502 if (--allocated == 0)
504 break; // Decrease the number in list and exit if empty.
511 * _ADCMD_FREE
513 * Frees some units then:
514 * 1) See if other ADCMD_ALLOCATE are in waiting state.
518 VOID _ADCMD_FREE(struct IOAudio *audioio, ETASK *eta)
520 BYTE unit, chan, final = 0;
521 EUNIT *channel;
522 UBYTE error = IONOERROR;
524 D(bug("NEWD: Arrived CMD_FREE from IOAudio (%x), unit(%d)\n", audioio,
525 audioio->ioa_Request.io_Unit));
527 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
531 chan = writechn[unit];
532 channel = eta->et_units[chan];
534 if (channel->eu_allockey == audioio->ioa_AllocKey)
536 //if(accessibili)
538 ResetUnit(channel); // Reset this one please.
539 eta->et_unitmask &= ~(1 << chan); // This channel is now free.
540 channel->eu_allockey = 0; // Not needed!
541 channel->eu_pri = -127; // Not needed!
543 D(bug("NEWD: CMD_FREE freed unit (%d)\n", chan));
545 //else error = ADIOERR_NOALLOCATION;
547 else
549 error = ADIOERR_NOALLOCATION;
552 unit &= ~(1 << chan);
553 final |= 1 << chan;
554 } while (unit);
557 D(bug("NEWD: Now i reply CMD_FREE from IOAudio (%x), unit(%d)\n", audioio,
558 audioio->ioa_Request.io_Unit));
560 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
561 audioio->ioa_Request.io_Error = error;
563 //Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,STOLEN_SIG);
564 Signal(ematsys->ts_calltask, STOLEN_SIG);
566 if (final) // Only if something now is freed touch the allocating waiting for...
568 ReAllocateUnits(eta);
569 // verificare ora il discorso dei locks.
576 * _CMD_WRITE
578 * See again the part of bad allockkey the signal there is wrong.
581 VOID _CMD_WRITE(struct IOAudio *audioio, ETASK *eta, EUNIT *unit)
583 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), emaunit (%d), cycles (%d), flags (%d)\n",
584 audioio, unit->eu_id, audioio->ioa_Cycles, audioio->ioa_Request.io_Flags));
585 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), period (%d), len (%d), pri (%d) key (%d)\n",
586 audioio, audioio->ioa_Period, audioio->ioa_Length,
587 audioio->ioa_Request.io_Message.mn_Node.ln_Pri, audioio->ioa_AllocKey));
588 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), data (%d) volume (%d)\n",
589 audioio, audioio->ioa_Data, audioio->ioa_Volume));
591 //D(bug("datalist\n",0, 0,0,0,0));
592 //ablo = audioio->ioa_Data;
593 //do
595 // D(bug("%d ",*ablo,0,0,0,0));
597 //}while((counter++) < 100);
598 //D(bug("\n",0, 0,0,0,0));
600 if (audioio->ioa_AllocKey == unit->eu_allockey)
602 audioio->ioa_Request.io_Flags &= ~IOF_QUICK;
603 AddTail(&unit->eu_writewaitlist,
604 &audioio->ioa_Request.io_Message.mn_Node); // Put the new one in the tail of the list.
605 audioio = (struct IOAudio*) RemHead(&unit->eu_writewaitlist); // Pick the head.
607 if ((unit->eu_status & UNIT_STOP) == 0) // If the unit isn't stopped.
609 if ((unit->eu_usingme == NULL) && (unit->eu_audioio == NULL)) // Precache free, executing free.
611 UnitCopyData(unit, audioio);
612 UnitInitAhi(unit);
614 if ((audioio = (struct IOAudio*) RemHead(
615 &unit->eu_writewaitlist)))
617 UnitCopyData(unit, audioio);
620 return;
623 if ((unit->eu_usingme != NULL) && (unit->eu_audioio == NULL))
625 UnitCopyData(unit, audioio);
626 return;
629 if ((unit->eu_usingme == NULL) && (unit->eu_audioio != NULL))
631 UnitInitAhi(unit);
632 UnitCopyData(unit, audioio);
634 return;
638 AddHead(&unit->eu_writewaitlist,
639 &audioio->ioa_Request.io_Message.mn_Node); // Reput if channel is stopped or cache and running are busy.
641 return;
643 else
645 D(bug("NEWD: CMD_WRITE bad allockey or inaccessible channel, IOAudio (%x), key (%d)\n",
646 audioio, audioio->ioa_AllocKey));
647 audioio->ioa_Request.io_Unit = NULL;
648 audioio->ioa_Request.io_Error = ADIOERR_NOALLOCATION;
650 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
651 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
653 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
655 ReplyMsg(&audioio->ioa_Request.io_Message);
661 * process_UnitsCmd
662 * ------------------
664 * Processes all the commands which interacts with all the units.
668 VOID process_UnitsCmd(struct IOAudio* MyIORequest, ETASK *eta)
670 switch (MyIORequest->ioa_Request.io_Command)
672 case ADCMD_ALLOCATE:
673 _ADCMD_ALLOCATE(MyIORequest, eta);
674 break;
676 case ADCMD_FREE:
677 _ADCMD_FREE(MyIORequest, eta);
678 break;
680 case ADCMD_PERVOL:
681 _ADCMD_PERVOL(MyIORequest, eta);
682 break;
684 case ADCMD_SETPREC:
685 _ADCMD_SETPREC(MyIORequest, eta);
686 break;
688 case ADCMD_FINISH:
689 _ADCMD_FINISH(MyIORequest, eta);
690 break;
692 case ADCMD_WAITCYCLE:
693 _ADCMD_WAITCYCLE(MyIORequest, eta);
694 break;
696 case ADCMD_LOCK:
697 _ADCMD_LOCK(MyIORequest, eta);
698 break;
700 case CMD_FLUSH:
701 _CMD_FLUSH(MyIORequest, eta);
702 break;
704 case CMD_RESET:
705 _CMD_RESET(MyIORequest, eta);
706 break;
708 case CMD_STOP:
709 _CMD_STOP(MyIORequest, eta);
710 break;
712 case CMD_START:
713 _CMD_START(MyIORequest, eta);
714 break;
716 case CMD_UPDATE:
717 _CMD_UPDATE(MyIORequest, eta);
718 break;
720 case CMD_CLEAR:
721 _CMD_CLEAR(MyIORequest, eta);
722 break;
724 case CMD_READ:
725 _CMD_READ(MyIORequest, eta);
726 break;
728 case CMD_ABORTIO: // This is a my command.
729 _CMD_ABORTIO(MyIORequest, eta);
730 break;
732 case CMD_CLOSE: // This is a my command.
733 _CMD_CLOSE(MyIORequest, eta);
734 break;
739 * free_ETask
740 * ------------
742 * Frees the ETASK system, all ports, closes the device etc..
746 VOID free_ETask(ETASK *eta)
748 CloseLibrary((struct Library*) eta->et_gfxbase);
750 free_EUnit(eta, eta->et_units[3]); // Free the units.
751 free_EUnit(eta, eta->et_units[2]);
752 free_EUnit(eta, eta->et_units[1]);
753 free_EUnit(eta, eta->et_units[0]);
755 if (!CheckIO((struct IORequest *) eta->et_openahireq))
757 AbortIO((struct IORequest *) eta->et_openahireq);
760 CloseDevice((struct IORequest *) eta->et_openahireq);
761 DeleteIORequest((struct IORequest *) eta->et_openahireq);
762 DeleteMsgPort((struct MsgPort*) eta->et_portahi);
763 DeleteMsgPort((struct MsgPort*) eta->et_portunits);
764 DeleteMsgPort((struct MsgPort*) eta->et_portunit3);
765 DeleteMsgPort((struct MsgPort*) eta->et_portunit2);
766 DeleteMsgPort((struct MsgPort*) eta->et_portunit1);
767 DeleteMsgPort((struct MsgPort*) eta->et_portunit0);
768 enode_FreeNode((ENODE*) eta);
772 * init_ETask
773 * ------------
775 * Initilizes the new style of manage the problem, so it allocs the unique task structure with 4 msgports for audio channels, 1 ports
776 * for manage requests for every channels, 4 structs for the units.
780 ETASK *init_ETask( VOID)
782 ETASK *eta;
784 if ((eta = (ETASK *) enode_AllocNode(sizeof(ETASK),
785 (unsigned long int) FindTask(NULL))))
787 eta->et_key = 1;
788 eta->et_unitmask = 0;
790 if ((eta->et_portunit0 = (struct MsgPort*) CreateMsgPort()))
792 if ((eta->et_portunit1 = (struct MsgPort*) CreateMsgPort()))
794 if ((eta->et_portunit2 = (struct MsgPort*) CreateMsgPort()))
796 if ((eta->et_portunit3 = (struct MsgPort*) CreateMsgPort()))
798 if ((eta->et_portunits
799 = (struct MsgPort*) CreateMsgPort()))
801 if ((eta->et_portahi
802 = (struct MsgPort*) CreateMsgPort()))
804 if ((eta->et_openahireq
805 = (struct AHIRequest*) CreateIORequest(
806 eta->et_portahi,
807 sizeof(struct AHIRequest))))
809 eta->et_openahireq->ahir_Version = 4;
811 if (!(OpenDevice(
812 "ahi.device",
813 AHI_DEFAULT_UNIT,
814 (struct IORequest*) eta->et_openahireq,
815 0)))
817 if ((eta->et_gfxbase
818 = (struct GfxBase*) OpenLibrary(
819 "graphics.library", 0L)))
821 if (eta->et_gfxbase->DisplayFlags
822 & PAL)
824 eta->et_clock = 3546895;
826 else
828 eta->et_clock = 3579545;
831 if ((eta->et_units[0] = init_EUnit(
832 eta, 1 << 0,
833 eta->et_portunit0)))
835 if ((eta->et_units[1]
836 = init_EUnit(
837 eta,
838 1 << 1,
839 eta->et_portunit1)))
841 if ((eta->et_units[2]
842 = init_EUnit(
843 eta,
844 1 << 2,
845 eta->et_portunit2)))
847 if ((eta->et_units[3]
848 = init_EUnit(
849 eta,
850 1 << 3,
851 eta->et_portunit3)))
853 eta->et_ports[0]
854 = eta->et_portunit0;
855 eta->et_ports[1]
856 = eta->et_portunit1;
857 eta->et_ports[2]
858 = eta->et_portunit2;
859 eta->et_ports[3]
860 = eta->et_portunit3;
861 NewList(
862 &eta->et_allocatelist); // The allocating waiting for.
863 eta->et_allocated
864 = 0; // No one in list.
866 return eta;
870 free_EUnit(
871 eta,
872 eta->et_units[2]);
875 free_EUnit(eta,
876 eta->et_units[1]);
879 free_EUnit(eta,
880 eta->et_units[0]);
883 CloseLibrary(
884 (struct Library*) eta->et_gfxbase);
887 if (!(CheckIO(
888 (struct IORequest*) eta->et_openahireq)))
890 AbortIO(
891 (struct IORequest*) eta->et_openahireq);
894 CloseDevice(
895 (struct IORequest*) eta->et_openahireq);
898 DeleteIORequest(
899 (struct IORequest *) eta->et_openahireq);
902 DeleteMsgPort((struct MsgPort*) eta->et_portahi);
905 DeleteMsgPort((struct MsgPort*) eta->et_portunits);
908 DeleteMsgPort((struct MsgPort*) eta->et_portunit3);
911 DeleteMsgPort((struct MsgPort*) eta->et_portunit2);
914 DeleteMsgPort((struct MsgPort*) eta->et_portunit1);
917 DeleteMsgPort((struct MsgPort*) eta->et_portunit0);
920 enode_FreeNode((ENODE*) eta);
923 return NULL;
928 * free_EUnit
929 * ------------
931 * Deletes the unit.
935 VOID free_EUnit(ETASK *estruct, EUNIT *unit)
938 if(IsListEmpty(&unit->eu_writewaitlist))
940 D(bug("NEWD: free_Unit() writewaitlist is empty (unit %d).\n", unit->eu_id));
942 else
944 D(bug("NEWD: free_Unit() writewaitlist is NOT empty (unit %d).\n", unit->eu_id));
947 if (IsListEmpty(&unit->eu_waitcyclelist))
949 D(bug("NEWD: free_Unit() waitcyclelist is empty (unit %d).\n", unit->eu_id));
951 else
953 D(bug("NEWD: free_Unit() waitcyclelist is NOT empty (unit %d).\n", unit->eu_id));
957 if (!(CheckIO((struct IORequest *) &unit->eu_ahireq)))
959 AbortIO((struct IORequest *) &unit->eu_ahireq);
962 DeleteIORequest((struct IORequest *) &unit->eu_ahireq);
967 * init_EUnit
968 * ------------
970 * Initializes the unit block. The unit is just an iorequest to interact with AHI or TIMER device.
971 * Returns the unit or NULL if fails.
973 * >Syn
974 * *unit = InitEUnit(*etask,channel,*msgport)
977 EUNIT *init_EUnit(ETASK *estruct, UBYTE channel, struct MsgPort *myport)
979 EUNIT *unit;
981 if ((unit = (EUNIT*) CreateIORequest(estruct->et_portahi, sizeof(EUNIT))))
983 NewList(&unit->eu_writewaitlist); // All the ones under writing.
984 NewList(&unit->eu_waitcyclelist); // All the ones under waitcycle.
985 unit->eu_clock = estruct->et_clock;
986 unit->eu_id = writechn[channel];
987 unit->eu_port = myport;
988 unit->eu_usingme = NULL;
989 unit->eu_audioio = NULL;
990 unit->eu_status = 0; // Status ready.
991 unit->eu_ahireq.ahir_Std.io_Message.mn_Node.ln_Pri = 0;
992 unit->eu_ahireq.ahir_Std.io_Command = CMD_WRITE;
993 unit->eu_ahireq.ahir_Std.io_Offset = 0;
994 unit->eu_ahireq.ahir_Type = AHIST_M8S;
995 unit->eu_ahireq.ahir_Link = NULL;
996 unit->eu_ahireq.ahir_Std.io_Message.mn_ReplyPort = estruct->et_portahi;
997 unit->eu_ahireq.ahir_Std.io_Device
998 = estruct->et_openahireq->ahir_Std.io_Device;
999 unit->eu_ahireq.ahir_Std.io_Unit
1000 = estruct->et_openahireq->ahir_Std.io_Unit;
1002 if (channel & (1 << 1 | 1 << 2))
1004 unit->eu_ahireq.ahir_Position = 0x10000; // right.
1006 else
1008 unit->eu_ahireq.ahir_Position = 0; // left.
1011 return unit;
1014 return NULL;
1018 * TaskBody
1019 * ----------
1021 * The slave process main function.
1024 VOID TaskBody( VOID)
1026 ULONG waitsignal, signalset;
1027 struct IOAudio *ioaudioreq;
1028 ETASK *eta;
1029 EUNIT *unit;
1030 BOOL close = TRUE;
1032 if ((eta = init_ETask()))
1034 global_eta = eta;
1035 eta->et_slavetask = FindTask(NULL);
1036 ematsys->ts_initio->ioa_Request.io_Error = IONOERROR;
1037 Signal(ematsys->ts_opentask, STOLEN_SIG);
1039 D(bug("NEWD: SLAVE PROCESS OPERATING.....\n"));
1041 waitsignal = (1 << eta->et_portunit0->mp_SigBit) | (1
1042 << eta->et_portunit1->mp_SigBit) | (1
1043 << eta->et_portunit2->mp_SigBit) | (1
1044 << eta->et_portunit3->mp_SigBit) | (1
1045 << eta->et_portunits->mp_SigBit) | (1
1046 << eta->et_portahi->mp_SigBit);
1048 while (close)
1050 signalset = Wait(waitsignal);
1052 if (signalset & (1 << eta->et_portunit0->mp_SigBit)) // PORT 0.
1054 while ((ioaudioreq
1055 = (struct IOAudio*) GetMsg(eta->et_portunit0)))
1057 _CMD_WRITE(ioaudioreq, eta, eta->et_units[0]);
1058 Signal(ioaudioreq->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1059 STOLEN_SIG);
1062 if (signalset & (1 << eta->et_portunit1->mp_SigBit)) // PORT 1.
1064 while ((ioaudioreq
1065 = (struct IOAudio*) GetMsg(eta->et_portunit1)))
1067 _CMD_WRITE(ioaudioreq, eta, eta->et_units[1]);
1068 Signal(ioaudioreq->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1069 STOLEN_SIG);
1072 if (signalset & (1 << eta->et_portunit2->mp_SigBit)) // PORT 2.
1074 while ((ioaudioreq
1075 = (struct IOAudio*) GetMsg(eta->et_portunit2)))
1077 _CMD_WRITE(ioaudioreq, eta, eta->et_units[2]);
1078 Signal(ioaudioreq->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1079 STOLEN_SIG);
1082 if (signalset & (1 << eta->et_portunit3->mp_SigBit)) // PORT 3.
1084 while ((ioaudioreq
1085 = (struct IOAudio*) GetMsg(eta->et_portunit3)))
1087 _CMD_WRITE(ioaudioreq, eta, eta->et_units[3]);
1088 Signal(ioaudioreq->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1089 STOLEN_SIG);
1092 //--------------------------------------------------------------------------------------------------------------------------
1093 if (signalset & (1 << eta->et_portahi->mp_SigBit)) // AHI REPLY PORT.
1095 while ((unit = (EUNIT*) GetMsg(eta->et_portahi)))// reply the I/Os.
1097 //D(bug("NEWD: this is the real ahi return unit(%d), ioreq (%d)\n",unit->eu_id, unit->eu_usingme));
1099 if ((ioaudioreq = unit->eu_usingme)) // This one is ended.
1101 if (unit->eu_savecycles) // No infinite in this != 0.
1103 if (--unit->eu_actcycles == 0)
1105 IPTR tmpunit =
1106 (IPTR) ioaudioreq->ioa_Request.io_Unit;
1107 tmpunit |= 1 << unit->eu_id;
1108 ioaudioreq->ioa_Request.io_Unit
1109 = (APTR) tmpunit;
1111 ioaudioreq->ioa_Request.io_Error = IONOERROR;
1113 ReplyMsg(&ioaudioreq->ioa_Request.io_Message);
1116 bug(
1117 "NEWD: AHI RETURNS Unit(%d), ioreq (%d)\n",
1118 unit->eu_id, ioaudioreq,
1119 0));
1122 unit->eu_usingme = NULL; // This informs that the unit now is free.
1124 if(unit->eu_audioio)
1126 UnitInitAhi(unit); // Ok send soon now the pre-cached.
1129 while(ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)) // Examine for this unit only one request in waiting status.
1131 D(bug("NEWD: Founded ioreq (%d) in writewaitlist, now i process it.\n",ioaudioreq,0,0,0,0));
1133 _CMD_WRITE(ioaudioreq,eta,unit);
1135 if(unit->eu_audioio)
1137 break; // If the precached is empty you can exit.
1141 unit->eu_usingme = NULL;
1143 if (unit->eu_audioio)
1145 UnitInitAhi(unit);
1147 if ((ioaudioreq
1148 = (struct IOAudio*) RemHead(
1149 &unit->eu_writewaitlist)))
1151 UnitCopyData(unit, ioaudioreq);
1153 D(bug("NEWD: PUT ioreq (%x) IN PRECACHE\n", ioaudioreq));
1156 else
1158 if ((ioaudioreq
1159 = (struct IOAudio*) RemHead(
1160 &unit->eu_writewaitlist)))
1162 UnitCopyData(unit, ioaudioreq);
1163 UnitInitAhi(unit);
1165 D(bug("NEWD: EXECUTED ioreq (%x)\n", ioaudioreq));
1167 if ((ioaudioreq
1168 = (struct IOAudio*) RemHead(
1169 &unit->eu_writewaitlist)))
1171 UnitCopyData(unit, ioaudioreq);
1173 D(bug("NEWD: PUT ioreq (%x) IN PRECACHE\n", ioaudioreq));
1178 else
1180 UnitInitRepAhi(unit);
1183 else // This zero infinite loop.
1185 UnitInitRepAhi(unit);
1188 ReplyWaitCycles(unit, eta); // Reply to whom was waiting for a cycle end.
1192 //--------------------------------------------------------------------------------------------------------------------------
1193 if (signalset & (1 << eta->et_portunits->mp_SigBit)) // ALL THE PORTS.
1195 while ((ioaudioreq
1196 = (struct IOAudio*) GetMsg(eta->et_portunits)))
1198 process_UnitsCmd(ioaudioreq, eta);
1200 if (ioaudioreq->ioa_Request.io_Command == CMD_CLOSE)
1202 D(bug("NEWD: RECEIVED CLOSE\n"));
1203 close = FALSE;
1204 break;
1208 //--------------------------------------------------------------------------------------------------------------------------
1211 else
1213 ematsys->ts_initio->ioa_Request.io_Error = IOERR_OPENFAIL; // Wrong! Inform my father...
1214 Signal(ematsys->ts_initio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1215 1 << ematsys->ts_initio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1219 VOID UnitReWrite(EUNIT *unit)
1221 struct IOAudio *ioaudioreq;
1223 if ((unit->eu_audioio != NULL) && (unit->eu_usingme == NULL))
1225 UnitInitAhi(unit);
1227 D(bug("NEWD: Cache presente ho initializzato unit %d\n", unit->eu_id));
1229 if ((ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1231 UnitCopyData(unit, ioaudioreq);
1234 else if ((unit->eu_audioio == NULL) && (unit->eu_usingme != NULL))
1236 D(bug("NEWD: Cache nulla ma ioreq in function %d\n", unit->eu_id));
1238 if ((ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1240 UnitCopyData(unit, ioaudioreq);
1244 else if ((unit->eu_audioio == NULL) && (unit->eu_usingme == NULL))
1246 D(bug("NEWD: Tutto vuoto provo l'init in unit %d\n", unit->eu_id));
1248 if ((ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1250 D(bug("NEWD: Tutto vuoto ma c' per l'init %d\n", unit->eu_id));
1252 UnitCopyData(unit, ioaudioreq);
1253 UnitInitAhi(unit);
1256 if ((ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1258 D(bug("NEWD: Tutto vuoto e anche per il cache %d\n", unit->eu_id));
1259 UnitCopyData(unit, ioaudioreq);
1264 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1265 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1266 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1271 * _ADCMD_LOCK
1273 * - This must be ended!!!!!!!
1277 VOID _ADCMD_LOCK(struct IOAudio *audioio, ETASK *eta)
1279 BYTE unit, chan, final = 0;
1280 EUNIT *channel;
1281 UBYTE error = IONOERROR;
1283 D(bug("NEWD: Arrived ADCMD_LOCK from IOAudio (%x), unit(%d)\n", audioio,
1284 audioio->ioa_Request.io_Unit));
1286 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1290 chan = writechn[unit]; // Get the lowest channel.
1291 channel = eta->et_units[chan];
1293 if (channel->eu_allockey == audioio->ioa_AllocKey)
1295 final |= 1 << chan; // Ok for this unit the command is successfull.
1297 // ????????????????????????????????????????????????
1300 else
1302 error = ADIOERR_NOALLOCATION;
1305 unit &= ~(1 << chan);
1306 } while (unit);
1308 else
1310 error = ADIOERR_NOALLOCATION;
1313 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
1314 audioio->ioa_Request.io_Error = error;
1315 Signal(ematsys->ts_calltask, STOLEN_SIG);
1320 * ADCMD_LOCK
1324 void audio_LOCK(struct IOAudio *audioio)
1326 ULONG oldsignals;
1328 ematsys->ts_calltask = FindTask(NULL);
1329 oldsignals = SetSignal(0, STOLEN_SIG);
1331 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1332 Wait(STOLEN_SIG);
1333 SetSignal(oldsignals, STOLEN_SIG);
1335 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1337 ReplyMsg(&audioio->ioa_Request.io_Message);
1341 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1345 * _ADCMD_FINISH
1347 * - This must be ended!!!!!!!
1351 VOID _ADCMD_FINISH(struct IOAudio *audioio, ETASK *eta)
1353 BYTE unit, chan, final = 0;
1354 EUNIT *channel;
1355 UBYTE error = IONOERROR;
1357 D(bug("NEWD: Arrived ADCMD_FINISH from IOAudio (%x), unit(%d)\n", audioio,
1358 audioio->ioa_Request.io_Unit));
1360 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1364 chan = writechn[unit]; // Get the lowest channel.
1365 channel = eta->et_units[chan];
1367 if (channel->eu_allockey == audioio->ioa_AllocKey)
1369 final |= 1 << chan; // Ok for this unit the command is successfull.
1371 // ????????????????????????????????????????????????
1374 else
1375 error = ADIOERR_NOALLOCATION;
1376 unit &= ~(1 << chan);
1377 } while (unit);
1379 else
1381 error = ADIOERR_NOALLOCATION;
1384 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
1385 audioio->ioa_Request.io_Error = error;
1386 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
1387 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1392 * ADCMD_FINISH
1396 void audio_FINISH(struct IOAudio *audioio)
1398 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1399 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1401 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1403 ReplyMsg(&audioio->ioa_Request.io_Message);
1407 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1412 * _ADCMD_PERVOL
1416 VOID _ADCMD_PERVOL(struct IOAudio *audioio, ETASK *eta)
1418 BYTE unit, chan, final = 0;
1419 EUNIT *channel;
1420 UBYTE error = IONOERROR;
1422 D(bug("NEWD: Arrived ADCMD_PERVOL from IOAudio (%x), unit(%d)\n", audioio,
1423 audioio->ioa_Request.io_Unit));
1425 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1429 chan = writechn[unit]; // Get the lowest channel.
1430 channel = eta->et_units[chan];
1431 if (channel->eu_allockey == audioio->ioa_AllocKey)
1433 final |= 1 << chan; // Ok for this unit the command is successfull.
1434 UnitAHIPerVol(channel, audioio);
1436 else
1438 error = ADIOERR_NOALLOCATION;
1441 unit &= ~(1 << chan);
1442 } while (unit);
1444 else
1446 error = ADIOERR_NOALLOCATION;
1449 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
1450 audioio->ioa_Request.io_Error = error;
1451 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, STOLEN_SIG);
1456 * ADCMD_PERVOL
1458 * this shoul work
1461 void audio_PERVOL(struct IOAudio *audioio)
1463 struct Task *oldtask;
1464 ULONG oldsignals;
1466 oldtask = audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask;
1467 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
1468 oldsignals = SetSignal(0, STOLEN_SIG);
1470 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1471 Wait(STOLEN_SIG);
1473 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = oldtask;
1474 SetSignal(oldsignals, STOLEN_SIG);
1476 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1478 ReplyMsg(&audioio->ioa_Request.io_Message);
1482 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1485 * ReplyWaitCycles
1486 * -----------------
1488 * Scans the waitcyclelist and if there are some IOAudio waiting for the end of the wave it reply them to their tasks.
1492 VOID ReplyWaitCycles(EUNIT *unit, ETASK *eta)
1494 struct IOAudio *waitio;
1496 while ((waitio = (struct IOAudio*) RemHead(&unit->eu_waitcyclelist)))
1498 D(bug("NEWD: ReplyWaitCycles(): Found IOAuido (%x) in waitcyclelist, now i reply it.\n",
1499 waitio));
1501 ReplyMsg(&waitio->ioa_Request.io_Message);
1507 * ADCMD_WAITCYCLE
1511 void audio_WAITCYCLE(struct IOAudio *audioio)
1513 UBYTE unit;
1515 D(bug("NEWD: Arrived ADCMD_WAITCYCLE from IOAudio (%x), unit(%d)\n",
1516 audioio, audioio->ioa_Request.io_Unit));
1518 unit = (IPTR) audioio->ioa_Request.io_Unit;
1520 PutMsg(global_eta->et_portunits, (struct Message*) audioio); // For the ADCMD_WAITCYCLE only one unit accepted but i send it to the allunit msgport.
1521 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1523 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1525 if (audioio->ioa_Request.io_Error == ADIOERR_NOALLOCATION)
1527 ReplyMsg(&audioio->ioa_Request.io_Message);
1529 else
1531 if (unit != (IPTR) audioio->ioa_Request.io_Unit) // If the value changed it isn't waiting for anyone so please reply.
1533 ReplyMsg(&audioio->ioa_Request.io_Message);
1541 * _ADCMD_WAITCYCLE
1545 VOID _ADCMD_WAITCYCLE(struct IOAudio *audioio, ETASK *eta)
1547 UBYTE unit, chan; // For the CMD_READ only one unit accepted.
1548 EUNIT *channel;
1550 unit = (IPTR) audioio->ioa_Request.io_Unit;
1551 chan = writechn[unit & 15];
1553 if ((channel = eta->et_units[chan]))
1555 if (audioio->ioa_AllocKey == channel->eu_allockey)
1557 D(bug("NEWD: Arrived ADCMD_WAITCYCLE from IOAudio (%x),for unit (%d)\n",
1558 audioio, channel->eu_id));
1560 if (channel->eu_usingme) // Yes there is a wave in execution.
1562 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1563 tmpunit |= (1 << channel->eu_id);
1564 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1566 audioio->ioa_Request.io_Error = IONOERROR;
1567 audioio->ioa_Request.io_Flags &= ~IOF_QUICK; // It becames async so clear IOF_QUICK.
1569 // Put the iorequest in waitcyclelist.
1570 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1571 1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1573 return;
1575 else // No, no wave in execution.
1577 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1578 tmpunit &= ~(1 << channel->eu_id);
1579 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1581 audioio->ioa_Request.io_Error = IONOERROR;
1582 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1583 1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1585 return;
1588 if (channel->eu_usingme)
1590 audioio->ioa_Data = (UBYTE*) channel->eu_usingme;
1592 else
1594 audioio->ioa_Data = NULL;
1597 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1598 tmpunit |= (1 << channel->eu_id);
1599 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1601 audioio->ioa_Request.io_Error = IONOERROR;
1602 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
1603 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1605 return;
1609 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1610 tmpunit &= ~(1 << channel->eu_id);
1611 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1613 audioio->ioa_Request.io_Error = ADIOERR_NOALLOCATION;
1614 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
1615 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1618 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1620 VOID StartWaiting(EUNIT *unit, ETASK *eta)
1622 struct IOAudio *audioio;
1624 if ((audioio = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1626 UnitCopyData(unit, audioio);
1627 UnitInitAhi(unit);
1629 if ((audioio = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)))
1631 UnitCopyData(unit, audioio);
1638 * _CMD_START
1640 * - Here is calles CMD_WRITE but it signals to the port. Pay attention or better remove it.
1643 VOID _CMD_START(struct IOAudio *audioio, ETASK *eta)
1645 BYTE unit, chan, final = 0;
1646 EUNIT *channel;
1647 UBYTE error = IONOERROR;
1649 D(bug("NEWD: Arrived CMD_START from IOAudio (%x), unit(%d)\n", audioio,
1650 audioio->ioa_Request.io_Unit));
1652 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1656 chan = writechn[unit]; // Get the lowest channel.
1657 channel = eta->et_units[chan];
1659 if (channel->eu_allockey == audioio->ioa_AllocKey)
1661 final |= 1 << chan; // Ok for this unit the command is successfull.
1662 channel->eu_status &= ~UNIT_STOP; // The unit now is ready.
1663 StartWaiting(channel, eta);
1665 else
1667 error = ADIOERR_NOALLOCATION;
1670 unit &= ~(1 << chan);
1671 } while (unit);
1673 else
1675 error = ADIOERR_NOALLOCATION;
1678 audioio->ioa_Request.io_Unit = (struct Unit*) ((IPTR) final);
1679 audioio->ioa_Request.io_Error = error;
1680 Signal(ematsys->ts_calltask, STOLEN_SIG);
1685 * ADCMD_START
1689 void audio_START(struct IOAudio *audioio)
1691 ULONG oldsignals;
1693 ematsys->ts_calltask = FindTask(NULL);
1694 oldsignals = SetSignal(0, STOLEN_SIG);
1696 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1697 Wait(STOLEN_SIG);
1698 SetSignal(oldsignals, STOLEN_SIG);
1700 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1702 ReplyMsg(&audioio->ioa_Request.io_Message);
1706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1710 * _CMD_STOP
1712 * - I have to stop the audio if the unit was outputting it. But it isn't removed now. I simply abort the AHI. Wait for a program
1713 * which uses differently CMD_STOP and CMD_START please.
1716 VOID _CMD_STOP(struct IOAudio *audioio, ETASK *eta)
1718 BYTE unit, chan, final = 0;
1719 EUNIT *channel;
1720 UBYTE error = IONOERROR;
1722 D(bug("NEWD: Arrived CMD_STOP from IOAudio (%x), unit(%d)\n", audioio,
1723 audioio->ioa_Request.io_Unit));
1725 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1729 chan = writechn[unit]; // Get the lowest channel.
1730 channel = eta->et_units[chan];
1732 if (channel->eu_allockey == audioio->ioa_AllocKey)
1734 final |= 1 << chan; // Ok for this unit the command is successfull.
1735 channel->eu_status |= UNIT_STOP; // The unit now is stopped.
1737 // stop the output if there is.
1739 if (channel->eu_usingme) // Is in execution ?
1741 if (!(CheckIO((struct IORequest *) &channel->eu_ahireq)))
1743 AbortIO((struct IORequest *) &channel->eu_ahireq);
1744 WaitIO((struct IORequest *) &channel->eu_ahireq);
1747 channel->eu_usingme = NULL; // For now i abort it but probably i have to pay attention more here.
1751 else
1753 error = ADIOERR_NOALLOCATION;
1756 unit &= ~(1 << chan);
1757 } while (unit);
1759 else
1761 error = ADIOERR_NOALLOCATION;
1764 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
1765 audioio->ioa_Request.io_Error = error;
1766 Signal(ematsys->ts_calltask, STOLEN_SIG);
1771 * CMD_STOP
1775 void audio_STOP(struct IOAudio *audioio)
1777 ULONG oldsignals;
1779 ematsys->ts_calltask = FindTask(NULL);
1780 oldsignals = SetSignal(0, STOLEN_SIG);
1782 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1783 //Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1784 Wait(STOLEN_SIG);
1785 SetSignal(oldsignals, STOLEN_SIG);
1787 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1789 ReplyMsg(&audioio->ioa_Request.io_Message);
1793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1797 * CMD_READ
1801 void audio_READ(struct IOAudio *audioio)
1803 D(bug("NEWD: Arrived CMD_READ from IOAudio (%x)\n", audioio));
1805 PutMsg(global_eta->et_portunits, (struct Message*) audioio); // For the CMD_READ only one unit accepted but i send it to the allunit msgport.
1806 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1808 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1810 ReplyMsg(&audioio->ioa_Request.io_Message);
1816 * _CMD_READ
1820 VOID _CMD_READ(struct IOAudio *audioio, ETASK *eta)
1822 UBYTE unit, chan; // For the CMD_READ only one unit accepted.
1823 EUNIT *channel;
1825 unit = (IPTR) audioio->ioa_Request.io_Unit;
1826 chan = writechn[unit & 15];
1828 if ((channel = eta->et_units[chan]))
1830 if (audioio->ioa_AllocKey == channel->eu_allockey)
1832 //if(accessible con io unit)
1834 D(bug("NEWD: Arrived CMD_READ from IOAudio (%x),for unit (%d)\n",
1835 audioio, channel->eu_id));
1837 if (channel->eu_usingme)
1839 audioio->ioa_Data = (UBYTE*) channel->eu_usingme;
1841 else
1843 audioio->ioa_Data = NULL;
1846 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1847 tmpunit |= (1 << channel->eu_id);
1848 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1850 audioio->ioa_Request.io_Error = IONOERROR;
1851 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,
1852 1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1854 return;
1859 IPTR tmpunit = (IPTR) audioio->ioa_Request.io_Unit;
1860 tmpunit &= ~(1 << channel->eu_id);
1861 audioio->ioa_Request.io_Unit = (APTR) tmpunit;
1863 audioio->ioa_Request.io_Error = ADIOERR_NOALLOCATION;
1864 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
1865 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1868 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1872 * CMD_RESET
1876 void audio_RESET(struct IOAudio *audioio)
1878 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1879 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1881 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1883 ReplyMsg(&audioio->ioa_Request.io_Message);
1887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1891 * ADCMD_FREE
1895 void audio_FREE(struct IOAudio *audioio)
1897 ULONG oldsignals;
1899 D(bug("NEWDD: Sendinf CMD_FREE from IOAudio (%x), unit(%d) key %d\n",
1900 audioio, audioio->ioa_Request.io_Unit, audioio->ioa_AllocKey));
1902 ematsys->ts_calltask = FindTask(NULL);
1903 oldsignals = SetSignal(0, STOLEN_SIG);
1905 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1906 Wait(STOLEN_SIG);
1908 SetSignal(oldsignals, STOLEN_SIG);
1910 D(bug("NEWDD: End of wait state for ADCMD_FREE IoAudio (%d), unit(%d)\n",
1911 audioio, audioio->ioa_Request.io_Unit));
1913 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1915 ReplyMsg(&audioio->ioa_Request.io_Message);
1919 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1923 * _CMD_FLUSH
1927 VOID _CMD_FLUSH(struct IOAudio *audioio, ETASK *eta)
1929 BYTE unit, chan, final = 0;
1930 EUNIT *channel;
1931 UBYTE error = IONOERROR;
1933 D(bug("NEWD: Arrived CMD_FLUSH from IOAudio (%x), unit(%d), replyport(%x)\n",
1934 audioio, audioio->ioa_Request.io_Unit, audioio->ioa_Request.io_Message.mn_ReplyPort));
1936 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
1940 chan = writechn[unit];
1941 channel = eta->et_units[chan];
1943 if (channel->eu_allockey == audioio->ioa_AllocKey)
1945 final |= 1 << chan;
1946 FlushUnit(channel);
1948 D(bug("NEWD: CMD_FLUSH for unit (%d)\n", chan));
1950 else
1952 error = ADIOERR_NOALLOCATION;
1955 unit &= ~(1 << chan);
1956 } while (unit);
1958 else
1960 error = ADIOERR_NOALLOCATION;
1963 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
1964 audioio->ioa_Request.io_Error = error;
1965 Signal(ematsys->ts_calltask, STOLEN_SIG);
1970 * CMD_FLUSH
1974 void audio_FLUSH(struct IOAudio *audioio)
1976 ULONG oldsignals;
1978 ematsys->ts_calltask = FindTask(NULL);
1980 oldsignals = SetSignal(0, STOLEN_SIG); // Change signal set....
1981 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
1982 Wait(STOLEN_SIG);
1983 SetSignal(oldsignals, STOLEN_SIG); // restore signal set.
1985 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
1987 ReplyMsg(&audioio->ioa_Request.io_Message);
1991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1995 * ADCMD_ALLOCATE
1999 void audio_ALLOCATE(struct IOAudio *audioio)
2001 struct Task *oldtask;
2002 ULONG oldsignals;
2004 D(bug("NEWD: ADCMD_ALLOCATE for IOAudio (%x) replyport (%x)\n", audioio,
2005 audioio->ioa_Request.io_Message.mn_ReplyPort));
2007 oldtask = audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask;
2008 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
2009 oldsignals = SetSignal(0, STOLEN_SIG);
2011 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
2012 Wait(STOLEN_SIG);
2014 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = oldtask;
2015 SetSignal(oldsignals, STOLEN_SIG);
2017 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
2019 if ((audioio->ioa_Request.io_Error == ADIOERR_ALLOCFAILED)
2020 && (audioio->ioa_Request.io_Flags & ADIOF_NOWAIT))
2022 ReplyMsg(&audioio->ioa_Request.io_Message);
2024 else if (audioio->ioa_Request.io_Error == IONOERROR)
2026 ReplyMsg(&audioio->ioa_Request.io_Message);
2031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2035 * CMD_WRITE
2039 void audio_WRITE(struct IOAudio *audioio)
2041 UBYTE unit, chan; // For the CMD_WRITE only one unit accepted.
2042 struct Task *oldtask;
2043 ULONG oldsignals;
2045 D(bug("NEWDD: Received ADCMD_WRITE from task %x\n", FindTask(NULL)));
2047 unit = (IPTR) audioio->ioa_Request.io_Unit;
2048 chan = writechn[unit & 15];
2050 oldtask = audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask;
2051 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
2052 oldsignals = SetSignal(0, STOLEN_SIG);
2054 PutMsg(global_eta->et_ports[chan], (struct Message*) audioio);
2055 Wait(STOLEN_SIG);
2057 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = oldtask;
2058 SetSignal(oldsignals, STOLEN_SIG);
2061 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2064 BOOL AbortIOUnit(struct IOAudio *audioio, EUNIT *unit)
2066 if (unit->eu_audioio == audioio) // Is in pre-cache?
2068 unit->eu_audioio = NULL;
2069 //audioio->ioa_Request.io_Error = IONOERROR;
2071 D(bug("NEWD: ABORTIO IOAudio %x was in pre-cache, now replied\n",
2072 audioio));
2073 return 1;
2076 if (unit->eu_usingme == audioio) // Is in execution ?
2078 if (!(CheckIO((struct IORequest *) &unit->eu_ahireq)))
2080 D(bug("NEWD: It was really in execution\n"));
2082 AbortIO((struct IORequest *) &unit->eu_ahireq);
2083 WaitIO((struct IORequest *) &unit->eu_ahireq);
2086 unit->eu_usingme = NULL;
2087 //audioio->ioa_Request.io_Error = IONOERROR;
2089 D(bug("NEWD: ABORTIO IOAudio %x was in execution, stopped and replied\n",
2090 audioio));
2092 return 1;
2094 return 0;
2099 * _CMD_ABORTIO
2101 * - Remember that AbortIO() could not suspend the wave soon but has to wait for the cycle end. Page 127 RKM.
2104 VOID _CMD_ABORTIO(struct IOAudio *audioio, ETASK *eta)
2106 UBYTE actunit = 0;
2107 BOOL result;
2109 D(bug("NEWD: Received CMD_ABORTIO for IOAudio %x\n", audioio));
2111 do // First of all verify if the ioaudio is the one present in each unit channel.
2113 if ((result = AbortIOUnit(audioio, eta->et_units[actunit])))
2115 break;
2117 } while (++actunit < 4);
2119 if (!result) // If it isn't surely it stay in any list. Remove it and reply with IOERR_ABORTED
2121 Remove(&audioio->ioa_Request.io_Message.mn_Node); // Whereever you are remove it.
2122 audioio->ioa_Request.io_Error = IOERR_ABORTED;
2124 D(bug("NEWD: ABORTIO IOAudio %x not in pre-cache not in execution\n",
2125 audioio));
2128 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, STOLEN_SIG);
2131 actunit = 0;
2135 UnitReWrite(eta->et_units[actunit]);
2136 } while(++actunit < 4);
2142 * CMD_ABORTIO
2146 VOID audio_ABORTIO(struct IOAudio *audioio, ETASK *eta)
2148 UWORD oldcmd;
2149 struct Task *oldtask;
2150 ULONG oldsignals;
2152 oldcmd = audioio->ioa_Request.io_Command;
2153 audioio->ioa_Request.io_Command = CMD_ABORTIO;
2155 oldtask = audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask;
2156 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
2157 oldsignals = SetSignal(0, STOLEN_SIG);
2158 PutMsg(eta->et_portunits, (struct Message*) audioio);
2160 Wait(STOLEN_SIG);
2162 audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask = oldtask;
2163 SetSignal(oldsignals, STOLEN_SIG);
2165 audioio->ioa_Request.io_Command = oldcmd;
2166 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
2167 ReplyMsg(&audioio->ioa_Request.io_Message);
2172 * _CMD_CLOSE
2176 VOID _CMD_CLOSE(struct IOAudio *audioio, ETASK *eta)
2178 D(bug("NEWD: SLAVE PROCESS OPERATING END by CMD_CLOSE\n"));
2180 free_ETask(eta);
2182 Signal(ematsys->ts_calltask, STOLEN_SIG);
2187 * CMD_CLOSE
2191 VOID audio_CLOSE(struct IOAudio *audioio, ETASK *eta)
2193 UWORD oldcmd;
2194 ULONG oldsignals;
2196 oldcmd = audioio->ioa_Request.io_Command;
2197 audioio->ioa_Request.io_Command = CMD_CLOSE;
2199 ematsys->ts_calltask = FindTask(NULL);
2200 oldsignals = SetSignal(0, STOLEN_SIG);
2202 PutMsg(eta->et_portunits, (struct Message*) audioio);
2203 Wait(STOLEN_SIG);
2205 SetSignal(oldsignals, STOLEN_SIG);
2206 audioio->ioa_Request.io_Command = oldcmd;
2209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2213 * _CMD_CLEAR
2217 VOID _CMD_CLEAR(struct IOAudio *audioio, ETASK *eta)
2219 BYTE unit, chan, final = 0;
2220 EUNIT *channel;
2221 UBYTE error = IONOERROR;
2223 D(bug("NEWD: Arrived CMD_CLEAR from IOAudio (%x), unit(%d)\n", audioio,
2224 audioio->ioa_Request.io_Unit));
2226 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
2230 chan = writechn[unit]; // Get the lowest channel.
2231 channel = eta->et_units[chan];
2233 if (channel->eu_allockey == audioio->ioa_AllocKey)
2235 final |= 1 << chan; // Ok for this unit the command is successfull.
2237 else
2239 error = ADIOERR_NOALLOCATION;
2242 unit &= ~(1 << chan);
2243 } while (unit);
2245 else
2247 error = ADIOERR_NOALLOCATION;
2250 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
2251 audioio->ioa_Request.io_Error = error;
2252 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
2253 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2258 * CMD_CLEAR
2262 void audio_CLEAR(struct IOAudio *audioio)
2264 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
2265 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2267 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
2269 ReplyMsg(&audioio->ioa_Request.io_Message);
2273 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2277 * _CMD_UPDATE
2281 VOID _CMD_UPDATE(struct IOAudio *audioio, ETASK *eta)
2283 BYTE unit, chan, final = 0;
2284 EUNIT *channel;
2285 UBYTE error = IONOERROR;
2287 D(bug("NEWD: Arrived CMD_UPDATE from IOAudio (%x), unit(%d)\n", audioio,
2288 audioio->ioa_Request.io_Unit));
2290 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
2294 chan = writechn[unit]; // Get the lowest channel.
2295 channel = eta->et_units[chan];
2297 if (channel->eu_allockey == audioio->ioa_AllocKey)
2299 final |= 1 << chan; // Ok for this unit the command is successfull.
2301 else
2303 error = ADIOERR_NOALLOCATION;
2306 unit &= ~(1 << chan);
2307 } while (unit);
2309 else
2311 error = ADIOERR_NOALLOCATION;
2314 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
2315 audioio->ioa_Request.io_Error = error;
2316 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
2317 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2322 * CMD_UPDATE
2326 void audio_UPDATE(struct IOAudio *audioio)
2328 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
2329 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2331 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
2333 ReplyMsg(&audioio->ioa_Request.io_Message);
2337 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2342 * _ADCMD_SETPREC
2346 VOID _ADCMD_SETPREC(struct IOAudio *audioio, ETASK *eta)
2348 BYTE unit, chan, final = 0;
2349 EUNIT *channel;
2350 UBYTE error = IONOERROR;
2352 D(bug("NEWD: Arrived ADCMD_SETPREC from IOAudio (%x), unit(%d)\n", audioio,
2353 audioio->ioa_Request.io_Unit));
2355 if ((unit = (((IPTR) audioio->ioa_Request.io_Unit) & 15)))
2359 chan = writechn[unit]; // Get the lowest channel.
2360 channel = eta->et_units[chan];
2362 if (channel->eu_allockey == audioio->ioa_AllocKey)
2364 final |= 1 << chan; // Ok for this unit the command is successfull.
2365 channel->eu_pri
2366 = audioio->ioa_Request.io_Message.mn_Node.ln_Pri; // Ok, for this unit change the priority.
2368 else
2370 error = ADIOERR_NOALLOCATION;
2373 unit &= ~(1 << chan);
2374 } while (unit);
2376 else
2378 error = ADIOERR_NOALLOCATION;
2381 audioio->ioa_Request.io_Unit = (struct Unit*) (IPTR) final;
2382 audioio->ioa_Request.io_Error = error;
2383 Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask, 1
2384 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2386 // Now, because the priority of the channel is modified retry, if there are, to allocate some waiting requests for.
2388 if (unit)
2390 ReAllocateUnits(eta);
2396 * ADCMD_SETPREC
2400 void audio_SETPREC(struct IOAudio *audioio)
2402 PutMsg(global_eta->et_portunits, (struct Message*) audioio);
2403 Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
2405 if ((audioio->ioa_Request.io_Flags & IOF_QUICK) == 0)
2407 ReplyMsg(&audioio->ioa_Request.io_Message);
2411 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////