home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.2 / Audio / EXPERIMENTAL / getpairs.src
Encoding:
Text File  |  1992-08-27  |  4.8 KB  |  164 lines

  1.  
  2. /* The following functions are provided with the tools for the sake
  3.  * of experimentation, but there are no direct examples of their
  4.  * use (yet).  Want to be sure that these meld consistently with
  5.  * already existing functions.
  6.  */
  7.  
  8. /* To request "any" stereo pair, use pair = -1;
  9.  * To request a specific stereo pair, use pair = {100,101,102,or 103}
  10.  * corresponding to channels 0 and 1, 0 and 2, 1 and 3 or 2 and 3
  11.  * respectively.  (Channels 0 and 3 are connected to the LEFT output
  12.  * channel, and channels 1 and 2 go to the RIGHT output).
  13.  *
  14.  * Values of 104 and 105 are special, representing "get two LEFT
  15.  * channels" (104) or "get two RIGHT channels" (105).  You do this
  16.  * so as to keep a sound on the same side without ping ponging back
  17.  * and forth as some programs do.
  18.  */
  19. int
  20. GetPair(pair)
  21.     LONG pair;
  22. {
  23.     int error, value;
  24.     struct ExtIOB *iob, controlIOB;
  25.  
  26.     iob = &controlIOB;
  27.     iob->ioa_Request.io_Device    = device;
  28.     iob->ioa_Request.io_Message.mn_ReplyPort = controlPort;
  29.  
  30.     InitBlock(iob,0);    /* init it for CMD_WRITE, then change */
  31.  
  32.     /* set precedence of the request for a channel */
  33.     iob->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
  34.  
  35.     /* Type of command is ALLOCATE */
  36.     iob->ioa_Request.io_Command = ADCMD_ALLOCATE;
  37.     if(pair == -1)
  38.     {    /* Point to the allocation map */ 
  39.         iob->ioa_Data = (UBYTE *)stereostuff;
  40.         
  41.         /* It contains 4 entries */
  42.         iob->ioa_Length = 4;
  43.     }
  44.     else if(pair >=100 && pair <= 105)
  45.     {    iob->ioa_Data = (UBYTE *)(&stereostuff[pair-100]);
  46.         iob->ioa_Length = 1;
  47.     }
  48.     else    /* chose a bad channel pair; cannot allocate it */
  49.     {    
  50.         return(-1);
  51.     }
  52.     /* Don't wait for allocation, channels
  53.      * should be available!  If we don't set
  54.      * ADIOF_NOWAIT, the task will idle waiting
  55.      * for a chance to allocate the channel, 
  56.      * looking again each time another task
  57.      * allocates or frees a channel.         
  58.      */
  59.     iob->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
  60.  
  61.     BeginIO(iob); 
  62.  
  63.     error = WaitIO(iob);  /* returns nonzero if error */
  64.     if(!(iob->ioa_Request.io_Flags & IOF_QUICK))
  65.     {    /* if flag not set, then the message
  66.          * was appended to the reply port 
  67.          * (was not quick I/O after all)  */
  68.         GetMsg(iob->ioa_Request.io_Message.mn_ReplyPort);
  69.     }
  70.     if(error)
  71.     {    return(-1);
  72.     }
  73.     /* Save the values... freeing the IOB on exit */
  74.     gotunit   = (iob->ioa_Request.io_Unit);
  75.     gotkey      = (iob->ioa_AllocKey);
  76.         
  77.     switch((LONG)(iob->ioa_Request.io_Unit))
  78.     {    
  79.         /* stereo allocations possible */
  80.  
  81.         case  3:    value = 100;    break;
  82.         case  5:    value = 101;    break;
  83.         case 10:    value = 102;    break;
  84.         case 12:    value = 103;    break;
  85.  
  86.         /* two-channel monophonic allocations */
  87.  
  88.         case  9:        value = 104;    break;
  89.         case  6:        value = 105;    break;
  90.         default:    value = -1;    break;
  91.     }
  92.     return(value);
  93. }
  94.  
  95. /* 
  96.  
  97. The reason for the odd choice of numbers is so that there
  98. would be no conflict (or misunderstanding) with GetChannel.
  99. Examine the code for GetChannel and you'll note that the
  100. unit value is saved away for future use.
  101.  
  102. If you get a stereo pair, the same alloc_key can be saved
  103. away for two different channels.  And if you have successfully
  104. allocated both channels with this single call, you have the
  105. right to store those values for the channels as though they
  106. are independent anyway.
  107.  
  108. Return value to be tested this way or the equivalent (I am sure
  109. that a lot of you can discern a much more elegant way of doing
  110. this).
  111.  
  112.     pair = GetStereoPair(-1);
  113.  
  114.     switch (pair) {
  115.         case 100:
  116.             key[0] = gotkey;  key[1] = gotkey;
  117.             unit[0] = 1;  unit[1] = 2;
  118.             break;
  119.         case 101:
  120.             key[0] = gotkey;  key[2] = gotkey;
  121.             unit[0] = 1;  unit[2] = 4;
  122.             break;
  123.         case 102:
  124.             key[1] = gotkey;  key[3] = gotkey;
  125.             unit[1] = 2;  unit[3] = 8;
  126.             break;
  127.         case 103:
  128.             key[2] = gotkey;  key[3] = gotkey;
  129.             unit[2] = 4;  unit[3] = 8;
  130.             break;
  131.         case 104:
  132.             key[0] = gotkey;  key[3] = gotkey;
  133.             unit[0] = 1;  unit[3] = 8;
  134.             break;
  135.         case 105:
  136.             key[1] = gotkey;  key[2] = gotkey;
  137.             unit[1] = 2;  unit[2] = 8;
  138.             break;
  139.         case -1:
  140.         default:
  141.             break;
  142.         };
  143.  
  144.  
  145. As a direct result of the above, if the USER keeps track of which
  146. channels he allocated, he can free them one at a time, or use them
  147. one at a time, even though the allocation key is common to both 
  148. channels.  Also this is useful for stopping both channels in a 
  149. single command, then to queue notes to both channels individually 
  150. and use a single command to start both channels at once.
  151.  
  152. The function "ControlChannel" will have to be modified to recognize
  153. channel pair numbers 100, 101, 102 and 103, and extract the appropriate
  154. key value and set the corresponding unit value so that both channels
  155. can be controlled at the same time.  (Corresponding unit values are
  156. listed in GetStereoPair above).   If both channel's notes are
  157. in sync as queued, they'll remain in sync when the queue floodgates
  158. are opened.  Though user can still Control the channels individually
  159. if desired, just by using the normal channel numbers 0, 1, 2 and 3
  160. if user owns those channels.
  161.  
  162. */
  163.  
  164.