#include "SendMorse.h" #define MORSE_C1000 3579 #define MORSE_PERIOD 500 #define MORSE_LENGTH 6 #define MORSE_SPACE 6 /* # of dits between words */ BYTE sinewave[8] = {0, 90, 127, 90, 0, -90, -127, -90}; struct Device *auDevice=0; struct IOAudio *audioIOB; struct IOAudio *aulockIOB; struct IOAudio *aufreeIOB; BYTE *chipaudio = 0; struct MsgPort *auReplyPort, *auLockPort; extern UBYTE *AllocMem(); extern struct MsgPort *CreatePort(); struct IOAudio *CreateAudioIO(); UBYTE GetAnyChannel(); void FreeAudioIO(); #define isalpha(c) (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z'))) #define isdigit(c) ((c >= '0') && (c <= '9')) long sendrate = 5, ditcycles, dahcycles, ditlength; main(argc,argv) int argc; char **argv; { short i; GetSoundStuff(); for (i = 1; i < argc; i++) { if (*argv[i] == '-') { sendrate = atoi(argv[i]+1); if (sendrate <= 0) finishup("usage: code [-sendrate] "); } else Work(argv[i]); } FreeAChannel(aufreeIOB); finishup("all done"); } GetSoundStuff() { int i; UBYTE chan; audioIOB = CreateAudioIO(); aulockIOB = CreateAudioIO(); aufreeIOB = CreateAudioIO(); if(audioIOB == 0 || aufreeIOB == 0 | aulockIOB == 0) finishup("out of memory!"); if ((chipaudio = (BYTE *)AllocMem(8L, MEMF_CHIP)) == 0) finishup("out of memory!"); for (i = 0; i < 8; i++) chipaudio[i] = sinewave[i]; if (OpenDevice("audio.device",0L,audioIOB,0L)) finishup ("audio device won't open!"); /* Get the device address for later use */ auDevice = audioIOB->ioa_Request.io_Device; /* Create ports for replies from the device */ auReplyPort = CreatePort(0L,0L); auLockPort = CreatePort(0L,0L); if(auReplyPort == 0 || auLockPort == 0) finishup("cannot create a port!"); /* * initialize port addresses and device fields * for all audio request blocks */ audioIOB->ioa_Request.io_Device = auDevice; aulockIOB->ioa_Request.io_Device = auDevice; audioIOB->ioa_Request.io_Message.mn_ReplyPort = auReplyPort; aulockIOB->ioa_Request.io_Message.mn_ReplyPort = auLockPort; chan = GetAnyChannel(audioIOB); /* Make the allocation keys match */ aulockIOB->ioa_AllocKey = audioIOB->ioa_AllocKey; /* Make the unit numbers match */ aulockIOB->ioa_Request.io_Unit = audioIOB->ioa_Request.io_Unit; LockAChannel(aulockIOB,chan); /* * If checkio returns true, it means the request has * been returned. This means the channel has been * stolen. */ if(CheckIO(aulockIOB)) finishup("A channel was stolen!"); /* * now assuming nothing stolen, setup and request * an output from that channel. */ audioIOB->ioa_Data = (UBYTE *)chipaudio; audioIOB->ioa_Length = 8/2; /* 4 WORDS in table */ audioIOB->ioa_Period = MORSE_PERIOD; /* from table */ audioIOB->ioa_Volume = 64; /* maximum */ audioIOB->ioa_Cycles = 1000; /* # of times */ audioIOB->ioa_Request.io_Command = CMD_WRITE; audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL; /* copy the audio block for freeing channels later */ *aufreeIOB = *audioIOB; } finishup(string) char *string; { if(auDevice) CloseDevice(audioIOB); if(chipaudio) FreeMem(chipaudio,8L); if(audioIOB) FreeAudioIO(audioIOB); if(aulockIOB) FreeAudioIO(aulockIOB); if(auReplyPort) DeletePort(auReplyPort); if(auLockPort) DeletePort(auLockPort); printf("%ls\n",string); exit(0); } /* newaudioblock.c */ struct IOAudio * CreateAudioIO() { struct IOAudio *iob; iob = (struct IOAudio *) AllocMem((long)sizeof(struct IOAudio), MEMF_CHIP | MEMF_CLEAR); return(iob); /* returns 0 if out of memory */ } void FreeAudioIO(iob) struct IOAudio *iob; { FreeMem(iob, (long)sizeof(struct IOAudio)); } /* lockachannel.c */ LockAChannel(lockiob,channel) struct IOAudio *lockiob; UBYTE channel; { /* tell it which channel to lock */ /* lockiob->ioa_Request.io_Unit = (struct Unit *)channel; */ lockiob->ioa_Request.io_Command = ADCMD_LOCK; lockiob->ioa_Request.io_Flags = 0; /* Send this command. It does not return to * the reply port unless and until either this * task frees the channel or another channel of * higher precedence steals it. Appropriate * to keep two reply ports, perhaps... one for * standard I/O replies, other for channel steal * requests. */ BeginIO(lockiob); } FreeAChannel(iob) struct IOAudio *iob; { /* allocation key and unit number must already be valid */ iob->ioa_Request.io_Command = ADCMD_FREE; iob->ioa_Request.io_Flags = IOF_QUICK; BeginIO(iob); WaitIO(iob); } /* getaudio.c */ UBYTE GetAnyChannel(iob) struct IOAudio *iob; { UBYTE anychan[4]; UBYTE mychan; int error; anychan[0] = 1; anychan[1] = 2; anychan[2] = 4; anychan[3] = 8; iob->ioa_Request.io_Message.mn_Node.ln_Pri = 20; iob->ioa_Request.io_Command = ADCMD_ALLOCATE; iob->ioa_Data = (UBYTE *)anychan; iob->ioa_Length = 4; iob->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK; BeginIO(iob); error = WaitIO(iob); /* returns nonzero if error */ if(!(iob->ioa_Request.io_Flags & IOF_QUICK)) GetMsg(iob->ioa_Request.io_Message.mn_ReplyPort); if(error) return(0); mychan = ((ULONG)(iob->ioa_Request.io_Unit)) & 0xFF; return(mychan); } #define MAX_LETTERS 47 char *letters[MAX_LETTERS] = { ".-", /* A */ "-...", /* B */ "-.-.", /* C */ "-..", /* D */ ".", /* E */ "..-.", /* F */ "--.", /* G */ "....", /* H */ "..", /* I */ ".---", /* J */ "-.-", /* K */ ".-..", /* L */ "--", /* M */ "-.", /* N */ "---", /* O */ ".--.", /* P */ "--.-", /* Q */ ".-.", /* R */ "...", /* S */ "-", /* T */ "..-", /* U */ "...-", /* V */ ".--", /* W */ "-..-", /* X */ "-.--", /* Y */ "--..", /* Z */ "-----", /* 0 */ ".----", /* 1 */ "..---", /* 2 */ "...--", /* 3 */ "....-", /* 4 */ ".....", /* 5 */ "-....", /* 6 */ "--...", /* 7 */ "---..", /* 8 */ "----.", /* 9 */ "--..--", /* , */ ".-.-.-", /* . */ "..--..", /* ? */ "-.-.-.", /* ; */ "---...", /* : */ "-..-.", /* / */ "-....-", /* - */ ".----.", /* ' */ "-.--.-", /* () */ "..--.-", /* _ */ }; Work(fname) char *fname; /* * Get strings and send them to the audio port. * * Dlen: 1000 millis/sec * 1/8 chars/dit * 1/25 min/chars * 1/60 secs/min */ { char *cptr, line[132]; FILE *file; if ((file = fopen(fname, "r")) == NULL) finishup("can't open a file"); ditlength = 75 / sendrate; /* In 20 milliseconds */ ditcycles = 12 * (MORSE_C1000 / MORSE_PERIOD); dahcycles = ditcycles * 3; while (fgets(line, 132, file)) { for (cptr = line; *cptr && (*cptr != '\n'); cptr++) { SendLetter(*cptr); PauseDit(3); } } fclose(file); } SendLetter(c) char c; /* * Send character c. */ { char *cptr, *temp = ",.?;:;/-,{}_", *findchar(); short i; if (c == ' ') { PauseDit(MORSE_SPACE); return; } if (isalpha(c)) c = tolower(c) - 'a'; else if (isdigit(c)) c = c - 'a' + 26; else { cptr = findchar(temp, c); c = 37 + cptr - temp; } cptr = letters[c]; i = 0; for ( ; *cptr != 0; cptr++, i++) { if (i) PauseDit(1); /* * We'll send each dit or dah. We know it's done when WaitIO * returns. I think. */ if (*cptr == '.') audioIOB->ioa_Cycles = ditcycles; else audioIOB->ioa_Cycles = dahcycles; BeginIO(audioIOB); WaitIO(audioIOB); } } char *findchar(s,c) char *s,c; { for ( ; *s; s++) if (*s == c) return(s); return(NULL); } PauseDit(ditcount) short ditcount; /* * Pause for ditcount dit periods. * * Do this by setting the timer and waiting for it. */ { Delay((long)(ditcount * ditlength)); }