home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 201.lha / SendMorse / SendMorse.c < prev    next >
C/C++ Source or Header  |  1988-12-27  |  8KB  |  382 lines

  1. #include "SendMorse.h"
  2.  
  3. #define        MORSE_C1000        3579
  4. #define        MORSE_PERIOD    500
  5. #define        MORSE_LENGTH    6
  6. #define        MORSE_SPACE        6            /* # of dits between words */
  7.  
  8. BYTE sinewave[8] = {0, 90, 127, 90, 0, -90, -127, -90};
  9.  
  10. struct Device    *auDevice=0;
  11. struct IOAudio    *audioIOB;
  12. struct IOAudio    *aulockIOB;
  13. struct IOAudio    *aufreeIOB;
  14. BYTE            *chipaudio = 0;
  15.  
  16. struct MsgPort *auReplyPort, *auLockPort;
  17.  
  18. extern UBYTE            *AllocMem();
  19. extern struct MsgPort    *CreatePort();
  20.  
  21. struct IOAudio            *CreateAudioIO();
  22. UBYTE                    GetAnyChannel();
  23. void                    FreeAudioIO();
  24.  
  25. #define isalpha(c)    (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
  26. #define isdigit(c)    ((c >= '0') && (c <= '9'))
  27.  
  28. long    sendrate = 5, ditcycles, dahcycles, ditlength;
  29.  
  30. main(argc,argv)
  31. int argc;
  32. char **argv;
  33. {
  34.     short i;
  35.  
  36.     GetSoundStuff();
  37.     for (i = 1; i < argc; i++)
  38.     {
  39.         if (*argv[i] == '-')
  40.         {
  41.             sendrate = atoi(argv[i]+1);
  42.             if (sendrate <= 0)
  43.                 finishup("usage: code [-sendrate] <filelist>");
  44.         }
  45.         else
  46.             Work(argv[i]);
  47.     }
  48.  
  49.     FreeAChannel(aufreeIOB);
  50.     finishup("all done");
  51. }
  52.  
  53.  
  54. GetSoundStuff()
  55. {
  56.     int        i;
  57.     UBYTE    chan;
  58.  
  59.     audioIOB  = CreateAudioIO();
  60.     aulockIOB = CreateAudioIO();
  61.     aufreeIOB = CreateAudioIO();
  62.  
  63.     if(audioIOB == 0 || aufreeIOB == 0 | aulockIOB == 0)
  64.         finishup("out of memory!");
  65.  
  66.     if ((chipaudio = (BYTE *)AllocMem(8L, MEMF_CHIP)) == 0)
  67.         finishup("out of memory!");
  68.     for (i = 0; i < 8; i++)
  69.         chipaudio[i] = sinewave[i];
  70.  
  71.     if (OpenDevice("audio.device",0L,audioIOB,0L))
  72.         finishup ("audio device won't open!");
  73.  
  74. /* Get the device address for later use */
  75.     auDevice = audioIOB->ioa_Request.io_Device;
  76.  
  77. /* Create ports for replies from the device */
  78.     auReplyPort = CreatePort(0L,0L);
  79.     auLockPort  = CreatePort(0L,0L);
  80.  
  81.     if(auReplyPort == 0 || auLockPort == 0) 
  82.         finishup("cannot create a port!");
  83.  
  84. /*
  85.  * initialize port addresses and device fields 
  86.  * for all audio request blocks 
  87.  */
  88.     audioIOB->ioa_Request.io_Device = auDevice;
  89.     aulockIOB->ioa_Request.io_Device = auDevice;
  90.  
  91.     audioIOB->ioa_Request.io_Message.mn_ReplyPort  = auReplyPort;
  92.     aulockIOB->ioa_Request.io_Message.mn_ReplyPort  = auLockPort;
  93.  
  94.     chan = GetAnyChannel(audioIOB);
  95.  
  96.     /* Make the allocation keys match */
  97.     aulockIOB->ioa_AllocKey = audioIOB->ioa_AllocKey;
  98.  
  99.     /* Make the unit numbers match */
  100.     aulockIOB->ioa_Request.io_Unit = audioIOB->ioa_Request.io_Unit;
  101.  
  102.     LockAChannel(aulockIOB,chan);
  103.  
  104. /*
  105.  * If checkio returns true, it means the request has
  106.  * been returned.  This means the channel has been
  107.  * stolen.
  108.  */
  109.  
  110.     if(CheckIO(aulockIOB))
  111.         finishup("A channel was stolen!");
  112.  
  113. /*
  114.  * now assuming nothing stolen, setup and request
  115.  * an output from that channel.
  116.  */
  117.     audioIOB->ioa_Data   = (UBYTE *)chipaudio;
  118.     audioIOB->ioa_Length = 8/2;         /* 4 WORDS in table */
  119.     audioIOB->ioa_Period = MORSE_PERIOD;    /* from table */
  120.     audioIOB->ioa_Volume = 64;            /* maximum */
  121.     audioIOB->ioa_Cycles = 1000;        /* # of times */
  122.  
  123.     audioIOB->ioa_Request.io_Command = CMD_WRITE;
  124.     audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
  125.  
  126.     /* copy the audio block for freeing channels later */
  127.     *aufreeIOB = *audioIOB;
  128.  
  129. }
  130.  
  131.  
  132. finishup(string)
  133. char *string;
  134. {
  135.     if(auDevice) CloseDevice(audioIOB);
  136.     if(chipaudio) FreeMem(chipaudio,8L);
  137.     if(audioIOB) FreeAudioIO(audioIOB);
  138.     if(aulockIOB) FreeAudioIO(aulockIOB);
  139.     if(auReplyPort) DeletePort(auReplyPort);
  140.     if(auLockPort)  DeletePort(auLockPort);
  141.  
  142.     printf("%ls\n",string);
  143.     exit(0);
  144. }
  145.  
  146.  
  147.  
  148. /* newaudioblock.c */
  149.  
  150. struct IOAudio *
  151. CreateAudioIO()
  152. {
  153.     struct IOAudio *iob;
  154.  
  155.     iob = (struct IOAudio *) AllocMem((long)sizeof(struct IOAudio),
  156.             MEMF_CHIP | MEMF_CLEAR);
  157.  
  158.     return(iob);    /* returns 0 if out of memory */
  159. }
  160.  
  161. void    
  162. FreeAudioIO(iob)
  163. struct IOAudio *iob;
  164. {
  165.     FreeMem(iob, (long)sizeof(struct IOAudio));
  166. }
  167.  
  168.  
  169.  
  170. /* lockachannel.c */
  171.  
  172. LockAChannel(lockiob,channel)
  173. struct IOAudio *lockiob;
  174. UBYTE channel;
  175. {
  176.     /* tell it which channel to lock */
  177.  
  178. /*    lockiob->ioa_Request.io_Unit = (struct Unit *)channel;    */
  179.  
  180.     lockiob->ioa_Request.io_Command = ADCMD_LOCK;
  181.     lockiob->ioa_Request.io_Flags = 0;
  182.  
  183.     /* Send this command.  It does not return to 
  184.      * the reply port unless and until either this
  185.      * task frees the channel or another channel of
  186.      * higher precedence steals it.  Appropriate
  187.      * to keep two reply ports, perhaps... one for
  188.      * standard I/O replies, other for channel steal
  189.      * requests. 
  190.      */
  191.     BeginIO(lockiob);
  192. }
  193.  
  194. FreeAChannel(iob)
  195. struct IOAudio *iob;
  196. {
  197.     /* allocation key and unit number must already be valid */
  198.     iob->ioa_Request.io_Command = ADCMD_FREE;
  199.     iob->ioa_Request.io_Flags = IOF_QUICK;
  200.     BeginIO(iob);
  201.     WaitIO(iob);
  202. }
  203.  
  204. /* getaudio.c */
  205.  
  206.  
  207. UBYTE
  208. GetAnyChannel(iob)
  209. struct IOAudio *iob;
  210. {
  211.     UBYTE anychan[4];
  212.     UBYTE mychan;
  213.     int error;
  214.  
  215.     anychan[0] = 1;
  216.     anychan[1] = 2;
  217.     anychan[2] = 4;
  218.     anychan[3] = 8;
  219.  
  220.     iob->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
  221.     iob->ioa_Request.io_Command = ADCMD_ALLOCATE;
  222.     iob->ioa_Data = (UBYTE *)anychan;
  223.     iob->ioa_Length = 4;
  224.     iob->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
  225.     BeginIO(iob); 
  226.     error = WaitIO(iob);  /* returns nonzero if error */
  227.  
  228.     if(!(iob->ioa_Request.io_Flags & IOF_QUICK))
  229.         GetMsg(iob->ioa_Request.io_Message.mn_ReplyPort);
  230.     if(error)
  231.         return(0);
  232.     mychan = ((ULONG)(iob->ioa_Request.io_Unit)) & 0xFF;
  233.     return(mychan);
  234. }
  235.  
  236.  
  237.  
  238.  
  239. #define        MAX_LETTERS        47
  240. char *letters[MAX_LETTERS] =
  241. {
  242.     ".-",                /* A */
  243.     "-...",                /* B */
  244.     "-.-.",                /* C */
  245.     "-..",                /* D */
  246.     ".",                /* E */
  247.     "..-.",                /* F */
  248.     "--.",                /* G */
  249.     "....",                /* H */
  250.     "..",                /* I */
  251.     ".---",                /* J */
  252.     "-.-",                /* K */
  253.     ".-..",                /* L */
  254.     "--",                /* M */
  255.     "-.",                /* N */
  256.     "---",                /* O */
  257.     ".--.",                /* P */
  258.     "--.-",                /* Q */
  259.     ".-.",                /* R */
  260.     "...",                /* S */
  261.     "-",                /* T */
  262.     "..-",                /* U */
  263.     "...-",                /* V */
  264.     ".--",                /* W */
  265.     "-..-",                /* X */
  266.     "-.--",                /* Y */
  267.     "--..",                /* Z */
  268.     "-----",                /* 0 */
  269.     ".----",                /* 1 */
  270.     "..---",                /* 2 */
  271.     "...--",                /* 3 */
  272.     "....-",                /* 4 */
  273.     ".....",                /* 5 */
  274.     "-....",                /* 6 */
  275.     "--...",                /* 7 */
  276.     "---..",                /* 8 */
  277.     "----.",                /* 9 */
  278.     "--..--",                /* , */
  279.     ".-.-.-",                /* . */
  280.     "..--..",                /* ? */
  281.     "-.-.-.",                /* ; */
  282.     "---...",                /* : */
  283.     "-..-.",                /* / */
  284.     "-....-",                /* - */
  285.     ".----.",                /* ' */
  286.     "-.--.-",                /* () */
  287.     "..--.-",                /* _ */
  288. };
  289.  
  290.  
  291.  
  292. Work(fname)
  293. char *fname;
  294. /*
  295.  * Get strings and send them to the audio port.
  296.  *
  297.  * Dlen: 1000 millis/sec * 1/8 chars/dit * 1/25 min/chars * 1/60 secs/min
  298.  */
  299. {
  300.     char    *cptr, line[132];
  301.     FILE    *file;
  302.  
  303.     if ((file = fopen(fname, "r")) == NULL)
  304.         finishup("can't open a file");
  305.     ditlength = 75 / sendrate;        /* In 20 milliseconds */
  306.      ditcycles = 12 * (MORSE_C1000 / MORSE_PERIOD);
  307.     dahcycles = ditcycles * 3;
  308.     while (fgets(line, 132, file))
  309.     {
  310.         for (cptr = line; *cptr && (*cptr != '\n'); cptr++)
  311.         {
  312.             SendLetter(*cptr);
  313.             PauseDit(3);
  314.         }
  315.     }
  316.     fclose(file);
  317. }
  318.  
  319.  
  320. SendLetter(c)
  321. char c;
  322. /*
  323.  * Send character c.
  324.  */
  325. {
  326.     char    *cptr, *temp = ",.?;:;/-,{}_", *findchar();
  327.     short    i;
  328.  
  329.     if (c == ' ')
  330.     {
  331.         PauseDit(MORSE_SPACE);
  332.         return;
  333.     }
  334.     if (isalpha(c))
  335.         c = tolower(c) - 'a';
  336.     else if (isdigit(c))
  337.         c = c - 'a' + 26;
  338.     else
  339.     {
  340.         cptr = findchar(temp, c);
  341.         c = 37 + cptr - temp;
  342.     }
  343.     cptr = letters[c];
  344.     i = 0;
  345.     for ( ; *cptr != 0; cptr++, i++)
  346.     {
  347.         if (i)
  348.             PauseDit(1);
  349.         /*
  350.          * We'll send each dit or dah.  We know it's done when WaitIO
  351.          *        returns.  I think.
  352.          */
  353.         if (*cptr == '.')
  354.             audioIOB->ioa_Cycles = ditcycles;
  355.         else
  356.             audioIOB->ioa_Cycles = dahcycles;
  357.         BeginIO(audioIOB);
  358.         WaitIO(audioIOB);
  359.     }
  360. }
  361.  
  362. char *findchar(s,c)
  363. char *s,c;
  364. {
  365.     for ( ; *s; s++)
  366.         if (*s == c)
  367.             return(s);
  368.     return(NULL);
  369. }
  370.  
  371.  
  372. PauseDit(ditcount)
  373. short ditcount;
  374. /*
  375.  * Pause for ditcount dit periods.
  376.  *
  377.  *        Do this by setting the timer and waiting for it.
  378.  */
  379. {
  380.     Delay((long)(ditcount * ditlength));
  381. }
  382.