home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d534 / term.lha / Term / Source.LZH / ToneDial.c < prev    next >
C/C++ Source or Header  |  1991-07-07  |  6KB  |  315 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Touch-tone period & cycle values are
  6.  *
  7.  *    (C) Copyright 1989 by Commodore-Amiga, Inc.
  8.  *
  9.  *    Name .....: ToneDial.c
  10.  *    Created ..: Wednesday 03-Jul-91 10:38
  11.  *    Revision .: 0
  12.  *
  13.  *    Date            Author          Comment
  14.  *    =========       ========        ====================
  15.  *    03-Jul-91       Olsen           Created this file!
  16.  *
  17.  * $Revision Header ********************************************************/
  18.  
  19. #include "TermGlobal.h"
  20.  
  21.     /* Audio device control. */
  22.  
  23. STATIC struct IOAudio    *Audio,
  24.             *Audio1,
  25.             *Audio2;
  26.  
  27.     /* A couple of reply ports. */
  28.  
  29. STATIC struct MsgPort    *AudioPort,
  30.             *Audio1Port,
  31.             *Audio2Port;
  32.  
  33.     /* Channel allocation scheme is as follow:
  34.      *
  35.      *    - allocate two channels either on the right or
  36.      *      the left side.
  37.      *
  38.      *    - if this fails, allocate two different stereo
  39.      *      channels.
  40.      */
  41.  
  42. STATIC UBYTE Channels[] =
  43. {
  44.     1 | 8,
  45.     2 | 4,
  46.     1 | 4,
  47.     2 | 8
  48. };
  49.  
  50.     /* Cheapo square wave. */
  51.  
  52. STATIC BYTE __chip SquareWave[8] =
  53. {
  54.     0,127,127,0,0,-127,-127,0
  55. };
  56.  
  57.     /* Touch tone periods for NTSC machines. */
  58.  
  59. STATIC USHORT NTSC_Periods[16][2] = 
  60. {
  61.     { 475,335 },    /* 0 */
  62.     { 642,370 },    /* 1 */
  63.     { 642,335 },    /* 2 */
  64.     { 642,303 },    /* 3 */
  65.     { 581,370 },    /* 4 */
  66.     { 581,335 },    /* 5 */
  67.     { 581,303 },    /* 6 */
  68.     { 525,370 },    /* 7 */
  69.     { 525,335 },    /* 8 */
  70.     { 525,303 },    /* 9 */
  71.     { 475,370 },    /* * */
  72.     { 475,303 },    /* # */
  73.     { 642,274 },    /* A */
  74.     { 581,274 },    /* B */
  75.     { 525,274 },    /* C */
  76.     { 475,274 },    /* D */
  77. };
  78.  
  79.     /* Touch tone periods for PAL machines. */
  80.  
  81. STATIC USHORT PAL_Periods[16][2] = 
  82. {
  83.     { 471,332 },    /* 0 */
  84.     { 636,367 },    /* 1 */
  85.     { 636,332 },    /* 2 */
  86.     { 636,300 },    /* 3 */
  87.     { 576,367 },    /* 4 */
  88.     { 576,332 },    /* 5 */
  89.     { 576,300 },    /* 6 */
  90.     { 520,367 },    /* 7 */
  91.     { 520,332 },    /* 8 */
  92.     { 520,300 },    /* 9 */
  93.     { 471,367 },    /* * */
  94.     { 471,300 },    /* # */
  95.     { 636,271 },    /* A */
  96.     { 576,271 },    /* B */
  97.     { 520,271 },    /* C */
  98.     { 471,271 }    /* D */
  99. };
  100.  
  101.     /* Length of each tone given in audio cycles. */
  102.  
  103. USHORT Cycles[16][2] = 
  104. {
  105.     { 106,150 },    /* 0 */
  106.     {  96,166 },    /* 1 */
  107.     { 106,204 },    /* 2 */
  108.     { 118,250 },    /* 3 */
  109.     {  96,150 },    /* 4 */
  110.     { 106,184 },    /* 5 */
  111.     { 118,226 },    /* 6 */
  112.     {  96,136 },    /* 7 */
  113.     { 106,166 },    /* 8 */
  114.     { 118,204 },    /* 9 */
  115.     {  96,124 },    /* * */
  116.     { 118,186 },    /* # */
  117.     { 130,304 },    /* A */
  118.     { 130,276 },    /* B */
  119.     { 130,250 },    /* C */
  120.     { 130,226 }    /* D */
  121. };
  122.  
  123.     /* The tone codes we know. */
  124.  
  125. UBYTE *Codes = "0123456789*#ABCD";
  126.  
  127.     /* DeleteTone():
  128.      *
  129.      *    Free the resources allocated for touch-tone dialing.
  130.      */
  131.  
  132. VOID
  133. DeleteTone()
  134. {
  135.     if(Audio2)
  136.     {
  137.         FreeVec(Audio2);
  138.  
  139.         Audio2 = NULL;
  140.     }
  141.  
  142.     if(Audio2Port)
  143.     {
  144.         DeleteMsgPort(Audio2Port);
  145.  
  146.         Audio2Port = NULL;
  147.     }
  148.  
  149.     if(Audio1)
  150.     {
  151.         FreeVec(Audio1);
  152.  
  153.         Audio1 = NULL;
  154.     }
  155.  
  156.     if(Audio1Port)
  157.     {
  158.         DeleteMsgPort(Audio1Port);
  159.  
  160.         Audio1Port = NULL;
  161.     }
  162.  
  163.     if(Audio)
  164.     {
  165.         if(Audio -> ioa_Request . io_Device)
  166.             CloseDevice(Audio);
  167.  
  168.         DeleteIORequest(Audio);
  169.  
  170.         Audio = NULL;
  171.     }
  172.  
  173.     if(AudioPort)
  174.     {
  175.         DeleteMsgPort(AudioPort);
  176.  
  177.         AudioPort = NULL;
  178.     }
  179. }
  180.  
  181.     /* CreateTone():
  182.      *
  183.      *    Allocate the resources required for touch-tone dialing.
  184.      */
  185.  
  186. STATIC BYTE
  187. CreateTone()
  188. {
  189.     if(AudioPort = CreateMsgPort())
  190.     {
  191.         if(Audio = (struct IOAudio *)CreateIORequest(AudioPort,sizeof(struct IOAudio)))
  192.         {
  193.             Audio -> ioa_Request . io_Message . mn_Node . ln_Pri    = 10;
  194.             Audio -> ioa_Data                    = Channels;
  195.             Audio -> ioa_Length                    = sizeof(Channels);
  196.  
  197.             if(!OpenDevice(AUDIONAME,0,Audio,0))
  198.             {
  199.                 Audio -> ioa_Request . io_Command    = CMD_WRITE;
  200.                 Audio -> ioa_Request . io_Flags        = ADIOF_PERVOL;
  201.                 Audio -> ioa_Data            = SquareWave;
  202.                 Audio -> ioa_Length            = 8;
  203.                 Audio -> ioa_Volume            = 32;
  204.  
  205.                 if(Audio1Port = CreateMsgPort())
  206.                 {
  207.                     if(Audio1 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_PUBLIC))
  208.                     {
  209.                         CopyMem(Audio,Audio1,sizeof(struct IOAudio));
  210.  
  211.                         Audio1 -> ioa_Request . io_Message . mn_ReplyPort    = Audio1Port;
  212.                         Audio1 -> ioa_Request . io_Unit                = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD0|DMAF_AUD1));
  213.  
  214.                         if(Audio2Port = CreateMsgPort())
  215.                         {
  216.                             if(Audio2 = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_PUBLIC))
  217.                             {
  218.                                 CopyMem(Audio,Audio2,sizeof(struct IOAudio));
  219.  
  220.                                 Audio2 -> ioa_Request . io_Message . mn_ReplyPort    = Audio2Port;
  221.                                 Audio2 -> ioa_Request . io_Unit                = (APTR)((ULONG)Audio -> ioa_Request . io_Unit & (DMAF_AUD2|DMAF_AUD3));
  222.  
  223.                                 return(TRUE);
  224.                             }
  225.                         }
  226.                     }
  227.                 }
  228.             }
  229.         }
  230.  
  231.         DeleteTone();
  232.     }
  233.  
  234.     return(FALSE);
  235. }
  236.  
  237.     /* ToneDial(UBYTE *Number):
  238.      *
  239.      *    Dial a number using touch-tone coding, produce the
  240.      *    sounds using the Amiga audio hardware.
  241.      */
  242.  
  243. BYTE
  244. ToneDial(UBYTE *Number)
  245. {
  246.     SHORT i,j;
  247.  
  248.         /* Resources ready? */
  249.  
  250.     if(!Audio)
  251.     {
  252.         if(!CreateTone())
  253.             return(FALSE);
  254.     }
  255.  
  256.         /* Check TV system (i.e. crystal frequency). */
  257.  
  258.     if(GfxBase -> DisplayFlags & PAL)
  259.     {
  260.         for(i = 0 ; i < strlen(Number) ; i++)
  261.         {
  262.             for(j = 0 ; j < 16 ; j++)
  263.             {
  264.                 if(ToUpper(Number[i]) == Codes[j])
  265.                 {
  266.                     Audio1 -> ioa_Cycles    = Cycles[j][0];
  267.                     Audio1 -> ioa_Period    = PAL_Periods[j][0];
  268.  
  269.                     Audio2 -> ioa_Period    = PAL_Periods[j][1];
  270.                     Audio2 -> ioa_Cycles    = Cycles[j][1];
  271.  
  272.                     BeginIO(Audio1);
  273.                     BeginIO(Audio2);
  274.  
  275.                     WaitIO(Audio1);
  276.                     WaitIO(Audio2);
  277.  
  278.                     Delay(4);
  279.  
  280.                     break;
  281.                 }
  282.             }
  283.         }
  284.     }
  285.     else
  286.     {
  287.         for(i = 0 ; i < strlen(Number) ; i++)
  288.         {
  289.             for(j = 0 ; j < 16 ; j++)
  290.             {
  291.                 if(Number[i] == Codes[j])
  292.                 {
  293.                     Audio1 -> ioa_Cycles    = Cycles[j][0];
  294.                     Audio1 -> ioa_Period    = NTSC_Periods[j][0];
  295.  
  296.                     Audio2 -> ioa_Cycles    = Cycles[j][1];
  297.                     Audio2 -> ioa_Period    = NTSC_Periods[j][1];
  298.  
  299.                     BeginIO(Audio1);
  300.                     BeginIO(Audio2);
  301.  
  302.                     WaitIO(Audio1);
  303.                     WaitIO(Audio2);
  304.  
  305.                     Delay(4);
  306.  
  307.                     break;
  308.                 }
  309.             }
  310.         }
  311.     }
  312.  
  313.     return(TRUE);
  314. }
  315.