morse.c revision 29018
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1988, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 332537Spst 342537Spst/* 352537Spst * Taught to send *real* morse by Lyndon Nerenberg (VE7TCP/VE6BBM) 362537Spst * <lyndon@orthanc.com> 372537Spst */ 382537Spst 392537Spst#ifndef lint 402537Spststatic char copyright[] = 412537Spst"@(#) Copyright (c) 1988, 1993\n\ 422537Spst The Regents of the University of California. All rights reserved.\n"; 431590Srgrimes#endif /* not lint */ 4467467Sru 451590Srgrimes#ifndef lint 461590Srgrimesstatic char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93"; 471590Srgrimes#endif /* not lint */ 481590Srgrimes 4987628Sdwmalone#include <stdio.h> 501590Srgrimes#include <ctype.h> 5187628Sdwmalone#include <locale.h> 5272109Scharnier#include <stdlib.h> 5387628Sdwmalone 541590Srgrimes#ifdef SPEAKER 5587628Sdwmalone#include <machine/speaker.h> 5687628Sdwmalone#include <fcntl.h> 5787628Sdwmalone#endif 581590Srgrimes 591590Srgrimesstruct morsetab { 601590Srgrimes char inchar; 611590Srgrimes char *morse; 621590Srgrimes}; 631590Srgrimes 641590Srgrimesstatic struct morsetab mtab[] = { 651590Srgrimes 662537Spst /* letters */ 672537Spst 682537Spst 'a', ".-", 692537Spst 'b', "-...", 701590Srgrimes 'c', "-.-.", 711590Srgrimes 'd', "-..", 72100521Sume 'e', ".", 73100521Sume 'f', "..-.", 7423693Speter 'g', "--.", 7523693Speter 'h', "....", 761590Srgrimes 'i', "..", 771590Srgrimes 'j', ".---", 781590Srgrimes 'k', "-.-", 791590Srgrimes 'l', ".-..", 8023693Speter 'm', "--", 8123693Speter 'n', "-.", 82202191Sed 'o', "---", 8311759Sache 'p', ".--.", 8423693Speter 'q', "--.-", 851590Srgrimes 'r', ".-.", 8664775Sbrian 's', "...", 871590Srgrimes 't', "-", 881590Srgrimes 'u', "..-", 891590Srgrimes 'v', "...-", 90168632Sdes 'w', ".--", 91106250Ssobomax 'x', "-..-", 9274586Sache 'y', "-.--", 931590Srgrimes 'z', "--..", 94150316Sdds 951590Srgrimes /* digits */ 9692920Simp 9792920Simp '0', "-----", 9892920Simp '1', ".----", 9992920Simp '2', "..---", 1001590Srgrimes '3', "...--", 10187229Smarkm '4', "....-", 102102944Sdwmalone '5', ".....", 1031590Srgrimes '6', "-....", 1041590Srgrimes '7', "--...", 1051590Srgrimes '8', "---..", 1062589Spst '9', "----.", 1072537Spst 108168635Sdes /* punctuation */ 1091590Srgrimes 110100521Sume ',', "--..--", 111100521Sume '.', ".-.-.-", 112100521Sume '?', "..--..", 113100521Sume '/', "-..-.", 114100521Sume '-', "-....-", 115100521Sume '=', "-...-", /* BT */ 11699249Smini ':', "---...", 11799249Smini ';', "-.-.-.", 11899249Smini '(', "-.--.", /* KN */ 119117010Sjmallett ')', "-.--.-", 120117010Sjmallett '$', "...-..-", 121117010Sjmallett '+', ".-.-.", /* AR */ 1221590Srgrimes 1231590Srgrimes /* prosigns without already assigned values */ 1241590Srgrimes 1251590Srgrimes '#', ".-...", /* AS */ 1261590Srgrimes '@', "...-.-", /* SK */ 1271590Srgrimes '*', "...-.", /* VE */ 1281590Srgrimes '%', "-...-.-", /* BK */ 1291590Srgrimes 1301590Srgrimes '\0', "" 1311590Srgrimes}; 1321590Srgrimes 1331590Srgrimes 1342537Spststatic struct morsetab iso8859tab[] = { 1352537Spst '�', ".--.-", 1362537Spst '�', ".--.-", 1372537Spst '�', ".--.-", 1382537Spst '�', ".-.-", 1392537Spst '�', "-.-..", 1401590Srgrimes '�', "..-..", 1411590Srgrimes '�', "..-..", 14227169Scharnier '�', "-..-.", 1431590Srgrimes '�', "---.", 1441590Srgrimes '�', "..--", 1452589Spst 1462589Spst '\0', "" 1472589Spst}; 14827169Scharnier 149102944Sdwmalonestatic struct morsetab koi8rtab[] = { 15027169Scharnier /* 151146466Sru * the cyrillic alphabet; you'll need a KOI8R font in order 152168635Sdes * to see the actual characters 15327169Scharnier */ 15427169Scharnier '�', ".-", /* a */ 15527169Scharnier '�', "-...", /* be */ 15627169Scharnier '�', ".--", /* ve */ 157102944Sdwmalone '�', "--.", /* ge */ 1582589Spst '�', "-..", /* de */ 15927169Scharnier '�', ".", /* ye */ 1602589Spst '�', ".", /* yo, the same as ye */ 16146662Sobrien '�', "...-", /* she */ 16287229Smarkm '�', "--..", /* ze */ 1632589Spst '�', "..", /* i */ 16446662Sobrien '�', ".---", /* i kratkoye */ 165150316Sdds '�', "-.-", /* ka */ 16646662Sobrien '�', ".-..", /* el */ 167220971Ssimon '�', "--", /* em */ 168220971Ssimon '�', "-.", /* en */ 169220971Ssimon '�', "---", /* o */ 170220971Ssimon '�', ".--.", /* pe */ 17146662Sobrien '�', ".-.", /* er */ 172220971Ssimon '�', "...", /* es */ 173220971Ssimon '�', "-", /* te */ 174220971Ssimon '�', "..-", /* u */ 175220971Ssimon '�', "..-.", /* ef */ 17646662Sobrien '�', "....", /* kha */ 17746662Sobrien '�', "-.-.", /* ce */ 17846662Sobrien '�', "---.", /* che */ 17911811Sache '�', "----", /* sha */ 18011759Sache '�', "--.-", /* shcha */ 1812589Spst '�', "-.--", /* yi */ 1822589Spst '�', "-..-", /* myakhkij znak */ 1832589Spst '�', "..-..", /* ae */ 1842589Spst '�', "..--", /* yu */ 1852589Spst '�', ".-.-", /* ya */ 1862589Spst 1872589Spst '\0', "" 1882589Spst}; 18987229Smarkm 1902589Spstvoid show(const char *), play(const char *), morse(char); 1912589Spst 1922589Spststatic int pflag, sflag; 1932589Spststatic int wpm = 20; /* words per minute */ 1942589Spst#define FREQUENCY 600 1952589Spststatic int freq = FREQUENCY; 1962589Spst 1972589Spst#ifdef SPEAKER 1981590Srgrimes#define DASH_LEN 3 1991590Srgrimes#define CHAR_SPACE 3 2001590Srgrimes#define WORD_SPACE (7 - CHAR_SPACE - 1) 2011590Srgrimesstatic float dot_clock; 2021590Srgrimesint spkr; 2031590Srgrimestone_t sound; 2041590Srgrimes#endif 2051590Srgrimes 2061590Srgrimesstatic struct morsetab *hightab = iso8859tab; 2071590Srgrimes 2081590Srgrimesint 2091590Srgrimesmain(int argc, char **argv) 2101590Srgrimes{ 2111590Srgrimes extern char *optarg; 2121590Srgrimes extern int optind; 2131590Srgrimes register int ch; 2141590Srgrimes register char *p; 2151590Srgrimes 2161590Srgrimes while ((ch = getopt(argc, argv, "spw:f:")) != EOF) 2171590Srgrimes switch ((char) ch) { 2181590Srgrimes case 'f': 2191590Srgrimes freq = atoi(optarg); 2201590Srgrimes break; 22148566Sbillf case 'p': 2221590Srgrimes pflag = 1; 2231590Srgrimes break; 2241590Srgrimes case 's': 2251590Srgrimes sflag = 1; 22648566Sbillf break; 22723693Speter case 'w': 2281590Srgrimes wpm = atoi(optarg); 2291590Srgrimes break; 2301590Srgrimes case '?': 231102944Sdwmalone default: 2321590Srgrimes fputs("usage: morse [-s] [-p] [-w speed] [-f frequency] [string ...]\n", stderr); 23387229Smarkm exit(1); 2341590Srgrimes } 2351590Srgrimes if (pflag && sflag) { 236201140Sed fputs("morse: only one of -p and -s allowed\n", stderr); 23787229Smarkm exit(1); 2381590Srgrimes } 239117010Sjmallett if (pflag && ((wpm < 1) || (wpm > 60))) { 240117010Sjmallett fputs("morse: insane speed\n", stderr); 241117010Sjmallett exit(1); 242201140Sed } 243201140Sed if (pflag && (freq == 0)) 244201140Sed freq = FREQUENCY; 2451590Srgrimes 246201140Sed#ifdef SPEAKER 247201140Sed if (pflag) { 2481590Srgrimes if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) { 2495369Sjkh perror(SPEAKER); 2505369Sjkh exit(1); 2511590Srgrimes } 2521590Srgrimes dot_clock = wpm / 2.4; /* dots/sec */ 253201140Sed dot_clock = 1 / dot_clock; /* duration of a dot */ 2541590Srgrimes dot_clock = dot_clock / 2; /* dot_clock runs at twice */ 255201140Sed /* the dot rate */ 2561590Srgrimes dot_clock = dot_clock * 100; /* scale for ioctl */ 25787229Smarkm } 25823693Speter#endif 25923693Speter argc -= optind; 26087229Smarkm argv += optind; 2611590Srgrimes 26223693Speter if((p = getenv("LC_CTYPE")) || 2631590Srgrimes (p = getenv("LC_ALL")) || 2641590Srgrimes (p = getenv("LANG"))) { 26523693Speter if(strlen(p) >= sizeof(".KOI8-R") && 26623693Speter strcasecmp(&p[strlen(p) + 1 - sizeof(".KOI8-R")], ".KOI8-R") == 0) 2671590Srgrimes hightab = koi8rtab; 2681590Srgrimes } 2691590Srgrimes (void) setlocale(LC_CTYPE, ""); 2701590Srgrimes 271102944Sdwmalone if (*argv) { 2721590Srgrimes do { 27387229Smarkm for (p = *argv; *p; ++p) { 2741590Srgrimes morse(*p); 275201140Sed } 2761590Srgrimes morse(' '); 27787229Smarkm } while (*++argv); 2781590Srgrimes } else { 27964775Sbrian while ((ch = getchar()) != EOF) 28064775Sbrian morse(ch); 28164775Sbrian } 28264775Sbrian exit(0); 2831590Srgrimes} 2841590Srgrimes 2851590Srgrimesvoid 28623693Spetermorse(char c) 2871590Srgrimes{ 2881590Srgrimes struct morsetab *m; 2891590Srgrimes 290229403Sed if (isalpha((unsigned char)c)) 2911590Srgrimes c = tolower((unsigned char)c); 2921590Srgrimes if ((c == '\r') || (c == '\n')) 2931590Srgrimes c = ' '; 2941590Srgrimes if (c == ' ') { 2951590Srgrimes if (pflag) { 2961590Srgrimes play(" "); 2971590Srgrimes return; 2981590Srgrimes } else { 2991590Srgrimes show(""); 3001590Srgrimes return; 3011590Srgrimes } 302228992Suqs } 303228992Suqs for (m = ((unsigned char)c < 0x80? mtab: hightab); 30466563Sbrian m->inchar != '\0'; 30566563Sbrian m++) { 30666563Sbrian if (m->inchar == c) { 30766563Sbrian if (pflag) { 30866563Sbrian play(m->morse); 30966563Sbrian } else 31066563Sbrian show(m->morse); 31166563Sbrian } 31264775Sbrian } 31364775Sbrian} 31464775Sbrian 31564775Sbrianvoid 31664775Sbrianshow(const char *s) 31764775Sbrian{ 31864775Sbrian if (sflag) 31964775Sbrian printf(" %s", s); 32064775Sbrian else 32164775Sbrian for (; *s; ++s) 32264775Sbrian printf(" %s", *s == '.' ? "dit" : "dah"); 32364775Sbrian printf("\n"); 32464775Sbrian} 325126960Sbde 32664775Sbrianvoid 32764775Sbrianplay(const char *s) 32864775Sbrian{ 32964775Sbrian#ifdef SPEAKER 33064775Sbrian const char *c; 33164775Sbrian 33264775Sbrian for (c = s; *c != '\0'; c++) { 33364775Sbrian switch (*c) { 33464775Sbrian case '.': 33564775Sbrian sound.frequency = freq; 3361590Srgrimes sound.duration = dot_clock; 33765064Sbrian break; 33865064Sbrian case '-': 33965064Sbrian sound.frequency = freq; 3401590Srgrimes sound.duration = dot_clock * DASH_LEN; 3411590Srgrimes break; 34266675Sru case ' ': 34366675Sru sound.frequency = 0; 34465064Sbrian sound.duration = dot_clock * WORD_SPACE; 34565064Sbrian break; 34666675Sru default: 34765064Sbrian sound.duration = 0; 34865064Sbrian } 34965064Sbrian if (sound.duration) { 3501590Srgrimes if (ioctl(spkr, SPKRTONE, &sound) == -1) { 35165787Sbrian perror("ioctl play"); 3521590Srgrimes exit(1); 35365064Sbrian } 35465787Sbrian } 35565064Sbrian sound.frequency = 0; 35665787Sbrian sound.duration = dot_clock; 3571590Srgrimes if (ioctl(spkr, SPKRTONE, &sound) == -1) { 3581590Srgrimes perror("ioctl rest"); 3591590Srgrimes exit(1); 3605369Sjkh } 3611590Srgrimes } 3621590Srgrimes sound.frequency = 0; 36327169Scharnier sound.duration = dot_clock * CHAR_SPACE; 3641590Srgrimes ioctl(spkr, SPKRTONE, &sound); 3651590Srgrimes#endif 3661590Srgrimes} 3674991Spst