home *** CD-ROM | disk | FTP | other *** search
- #include <lattice/stdio.h>
- #include <exec/types.h>
- #include <devices/audio.h>
- #include <devices/timer.h>
-
- #define TICKS_PER_SEC (3579545.0)
- #define PRIORITY (100)
- #define SOUND_PRIORITY (50)
- #define MAXBUF (131000)
-
- extern struct MsgPort *CreatePort();
- extern struct IOAudio *GetMsg();
-
-
- int timOpened;
- int finOpened;
-
- UBYTE allocMap[] = {1,2,4,8};
- int inUse[] = {0,0,0,0};
-
- struct MsgPort *port5_ = NULL;
- struct MsgPort *port6_ = NULL;
- struct MsgPort *port7_ = NULL;
- struct MsgPort *port8_ = NULL;
- struct MsgPort *port9_ = NULL;
- struct MsgPort *port10_ = NULL;
- struct MsgPort *port11_ = NULL;
-
- struct IOAudio sIO1;
- struct IOAudio sIO2;
- struct IOAudio sIO3;
- struct IOAudio sIO4;
-
- struct IOAudio finishIO;
- struct IOAudio ctlIO;
- struct IOAudio flushIO;
-
- struct IOAudio *sIOarray_[4];
-
- struct timerequest timReq;
- long timMsg;
- struct MsgPort *timPort_ = NULL;
-
- int nextTry;
-
- static int doneInit = 0;
-
-
-
- /*
- ---------------------------------------------------------------------------
- audio_init
- ---------------------------------------------------------------------------
- Initializes the audio device.
- Receives:
- <nothing>
- Returns:
- int status -completion status
- 0 ==> OK
- ===========================================================================
- */
- audio_init()
- {
-
- doneInit = 1;
- /*
- Open the audio device:
- ======================*/
- if(!(port5_=CreatePort("s5",0))){
- return(2);
- }
- if(!(port6_=CreatePort("s6",0))){
- return(2);
- }
- if(!(port7_=CreatePort("s7",0))){
- return(2);
- }
- if(!(port8_=CreatePort("s8",0))){
- return(2);
- }
- if(!(port9_=CreatePort("ctrl2",0))){
- return(3);
- }
- if(!(port10_ = CreatePort("ctrl3",0))){
- return(3);
- }
- if(!(port11_ = CreatePort("ctrl4",0))){
- return(3);
- }
- if(OpenDevice(AUDIONAME,0,&finishIO,0)){
- finOpened = 0;
- return(4);
- }
- finOpened = 1;
- /*
- Initialize the audio request blocks:
- ====================================*/
- sIO1 = finishIO;
- sIO2 = finishIO;
- sIO3 = finishIO;
- sIO4 = finishIO;
- flushIO = finishIO;
- ctlIO = finishIO;
- sIO1.ioa_Request.io_Message.mn_ReplyPort = port5_;
- sIO2.ioa_Request.io_Message.mn_ReplyPort = port6_;
- sIO3.ioa_Request.io_Message.mn_ReplyPort = port7_;
- sIO4.ioa_Request.io_Message.mn_ReplyPort = port8_;
- finishIO.ioa_Request.io_Message.mn_ReplyPort = port9_;
- flushIO.ioa_Request.io_Message.mn_ReplyPort = port10_;
- ctlIO.ioa_Request.io_Message.mn_ReplyPort = port11_;
-
- finishIO.ioa_Request.io_Flags = IOF_QUICK;
- finishIO.ioa_Request.io_Command = ADCMD_FINISH;
- finishIO.ioa_Data = NULL;
- finishIO.ioa_Length = 0;
- flushIO.ioa_Request.io_Flags = IOF_QUICK;
- flushIO.ioa_Request.io_Command = CMD_FLUSH;
- flushIO.ioa_Data = NULL;
- flushIO.ioa_Length = 0;
- flushIO.ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
- sIO1.ioa_Request.io_Command = CMD_WRITE;
- sIO1.ioa_Request.io_Flags = ADIOF_PERVOL|IOF_QUICK|ADIOF_SYNCCYCLE;
- sIO2.ioa_Request.io_Command = CMD_WRITE;
- sIO2.ioa_Request.io_Flags = ADIOF_PERVOL|IOF_QUICK|ADIOF_SYNCCYCLE;
- sIO3.ioa_Request.io_Command = CMD_WRITE;
- sIO3.ioa_Request.io_Flags = ADIOF_PERVOL|IOF_QUICK|ADIOF_SYNCCYCLE;
- sIO4.ioa_Request.io_Command = CMD_WRITE;
- sIO4.ioa_Request.io_Flags = ADIOF_PERVOL|IOF_QUICK|ADIOF_SYNCCYCLE;
- sIOarray_[0] = &(sIO1);
- sIOarray_[1] = &(sIO2);
- sIOarray_[2] = &(sIO3);
- sIOarray_[3] = &(sIO4);
- /*
- Open a timer:
- =============*/
- if(!(timPort_=CreatePort(0,0))){
- return(10);
- }
- timReq.tr_node.io_Message.mn_ReplyPort = timPort_;
- if(OpenDevice(TIMERNAME,UNIT_VBLANK,&timReq,0)){
- timOpened = 0;
- return(11);
- }
- timOpened = 1;
- timReq.tr_node.io_Message.mn_ReplyPort = timPort_;
- timReq.tr_node.io_Command = TR_ADDREQUEST;
- timReq.tr_node.io_Flags = 0;
- timReq.tr_node.io_Error = 0;
- timMsg = 1L << timPort_->mp_SigBit;
-
- nextTry = 0;
- return(0);
- }
-
-
-
- /*
- ---------------------------------------------------------------------------
- audio_sound
- ---------------------------------------------------------------------------
- Simulates the sound of a picked string.
- Receives:
- BYTE *s_ -pointer to the data for the sound
- int sLen -length of sound data in bytes
- int volume -volume (0 to 64)
- Returns:
- <nothing>
- ===========================================================================
- */
- audio_sound(s_,sLen,period,volume)
- BYTE *s_;
- ULONG sLen;
- int period;
- int volume;
- {
- struct IOAudio *mySound_;
- int ch;
- int u;
- int k;
-
- /*
- Check if there's any IO requests that have finished:
- ====================================================*/
- ch = GetChannel(&u,&k);
- /*
- Setup the number of repeats:
- ============================*/
- mySound_ = sIOarray_[ch];
- /*
- Setup the sound message:
- ========================*/
- mySound_->ioa_Data = s_;
- mySound_->ioa_Period = period;
- mySound_->ioa_Length = sLen;
- mySound_->ioa_Cycles = 1;
- mySound_->ioa_Volume = volume;
- mySound_->ioa_AllocKey = k;
- mySound_->ioa_Request.io_Flags = ADIOF_PERVOL;
- mySound_->ioa_Request.io_Unit = u;
- mySound_->ioa_Request.io_Message.mn_Node.ln_Pri = SOUND_PRIORITY;
- /*
- Play the sound:
- ===============*/
- BeginIO(mySound_);
- return(0);
- }
-
-
-
-
-
-
- /*
- ---------------------------------------------------------------------------
- audio_close
- ---------------------------------------------------------------------------
- Closes the audio device and de-allocates all associated memory.
- Receives:
- <nothing>
- Returns:
- <nothing>
- ===========================================================================
- */
- audio_close()
- {
- int i;
- struct IOAudio *msg_;
-
- if(doneInit){
- for(i=0; i<4; i++){
- flushIO.ioa_Request.io_Flags = IOF_QUICK;
- flushIO.ioa_Request.io_Command = ADCMD_FINISH;
- flushIO.ioa_AllocKey = sIOarray_[i]->ioa_AllocKey;
- flushIO.ioa_Request.io_Unit = sIOarray_[i]->ioa_Request.io_Unit;
- DoIO(&flushIO);
- finishIO.ioa_Request.io_Flags = IOF_QUICK;
- finishIO.ioa_Request.io_Command = ADCMD_FINISH;
- finishIO.ioa_AllocKey = sIOarray_[i]->ioa_AllocKey;
- finishIO.ioa_Request.io_Unit = sIOarray_[i]->ioa_Request.io_Unit;
- DoIO(&finishIO);
- ctlIO.ioa_Request.io_Command = ADCMD_FREE;
- ctlIO.ioa_Request.io_Flags = IOF_QUICK;
- ctlIO.ioa_Data = NULL;
- ctlIO.ioa_Length = 0;
- ctlIO.ioa_AllocKey = sIOarray_[i]->ioa_AllocKey;
- ctlIO.ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
- ctlIO.ioa_Request.io_Unit = sIOarray_[i]->ioa_Request.io_Unit;
- DoIO(&ctlIO);
- while(msg_=GetMsg(sIOarray_[i]->ioa_Request.io_Message.mn_ReplyPort)){
- }
- }
- }
- if(finOpened){
- CloseDevice(&finishIO);
- }
- if(timOpened){
- CloseDevice(&timReq);
- }
- if(timPort_){
- DeletePort(timPort_);
- }
- if(port5_){
- DeletePort(port5_);
- }
- if(port6_){
- DeletePort(port6_);
- }
- if(port7_){
- DeletePort(port7_);
- }
- if(port8_){
- DeletePort(port8_);
- }
- if(port9_){
- DeletePort(port9_);
- }
- if(port10_){
- DeletePort(port10_);
- }
- if(port11_){
- DeletePort(port11_);
- }
- return(0);
- }
-
-
-
- /*
- ---------------------------------------------------------------------------
- audio_delay
- ---------------------------------------------------------------------------
- Delays for a given amount of time. (Used for the time between
- notes.)
- Receives:
- int hsecs -length of time to delay in hundredths of a sec
- Returns:
- <nothing>
- ===========================================================================
- */
- audio_delay(hsecs)
- int hsecs;
- {
- timReq.tr_time.tv_secs = (int)(hsecs/100);
- timReq.tr_time.tv_micro = (int)(hsecs%100) * 10000;
- DoIO(&timReq);
- return(0);
- }
-
-
-
- /*
- ---------------------------------------------------------------------------
- EmptyPorts
- ---------------------------------------------------------------------------
- Used internaly by th audio routines. Waits for each pending
- audio request and frees the request when it finishes.
- Receives:
- <nothing>
- Returns:
- <nothing>
- ===========================================================================
- */
- EmptyPorts()
- {
- struct IOAudio *GetMsg();
- struct IOAudio *msg_;
- int i;
-
- for(i=0; i<4; i++){
- if(inUse[i]){
- while(msg_=GetMsg(sIOarray_[i]->ioa_Request.io_Message.mn_ReplyPort)){
- inUse[i] = 0;
- }
- if(!inUse[i]){
- ctlIO.ioa_Request.io_Command = ADCMD_FREE;
- ctlIO.ioa_Request.io_Flags = IOF_QUICK;
- ctlIO.ioa_Data = NULL;
- ctlIO.ioa_Length = 0;
- ctlIO.ioa_AllocKey = sIOarray_[i]->ioa_AllocKey;
- ctlIO.ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
- ctlIO.ioa_Request.io_Unit = sIOarray_[i]->ioa_Request.io_Unit;
- DoIO(&ctlIO);
- }
- }
- }
- return(0);
- }
-
-
-
- /*
- ---------------------------------------------------------------------------
- GetChannel
- ---------------------------------------------------------------------------
- Finds a free channel, or if they're all busy, cancels the
- oldest one and frees it.
- Receives:
- int *u_ -pointer to space for the unit
- int *k_ -pointer to space for the key
- Returns:
- int *u_ -the free channel's unit
- int *k_ -the free channel's key
- ===========================================================================
- */
- GetChannel(u_,k_)
- int *u_;
- int *k_;
- {
- int ch;
-
- while(1){
- EmptyPorts();
- ctlIO.ioa_Request.io_Command = ADCMD_ALLOCATE;
- ctlIO.ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
- ctlIO.ioa_Data = allocMap;
- ctlIO.ioa_AllocKey = 0;
- ctlIO.ioa_Request.io_Unit = NULL;
- ctlIO.ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
- ctlIO.ioa_Length = sizeof(allocMap);
- BeginIO(&ctlIO);
- if(!WaitIO(&ctlIO)){
- *u_ = (int)(ctlIO.ioa_Request.io_Unit);
- *k_ = (int)(ctlIO.ioa_AllocKey);
- break;
- }
- }
- while(1){
- for(ch=0; ch<4; ch++){
- if(!inUse[ch]){
- inUse[ch] = 1;
- nextTry = (ch+1)%4;
- return(ch);
- }
- }
- EmptyPorts();
- }
- }
-
-
-
- /*
- ---------------------------------------------------------------------------
- audio_free
- ---------------------------------------------------------------------------
- Frees all of the channels.
- Receives:
- <nothing>
- Returns:
- <nothing>
- ===========================================================================
- */
- audio_free()
- {
- while(inUse[0]+inUse[1]+inUse[2]+inUse[3]){
- EmptyPorts();
- }
- return(0);
- }
-