Make morse(6) realling playing the characters on the speaker.
Minor additions by me, mostly taken from the suggestion in PR # bin/709. Submitted by: lyndon@orthanc.com (Lyndon Nerenberg, VE7TCP/VE6BBM)
This commit is contained in:
parent
bce1959ae5
commit
d273a5f24f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10352
@ -45,14 +45,18 @@
|
||||
.Nm ppt
|
||||
.Op Ar string ...
|
||||
.Nm morse
|
||||
.Op Fl s Ar string ...
|
||||
.Op Fl p
|
||||
.Op Fl w Ar speed
|
||||
.Op Fl f Ar frequency
|
||||
.Op Fl s
|
||||
.Op Ar string ...
|
||||
.Sh DESCRIPTION
|
||||
The commands
|
||||
.Nm bcd ,
|
||||
.Nm ppt
|
||||
and
|
||||
.Nm morse
|
||||
reads the given input and reformats it in the form of punched cards,
|
||||
read the given input and reformat it in the form of punched cards,
|
||||
paper tape or morse code respectively.
|
||||
Acceptable input are command line arguments or the standard input.
|
||||
.Pp
|
||||
@ -62,6 +66,70 @@ Available option:
|
||||
The
|
||||
.Fl s
|
||||
option for morse produces dots and dashes rather than words.
|
||||
.It Fl p
|
||||
Send morse the real way. This only works if your system has sound
|
||||
support and if the program understands your audio hardware.
|
||||
.It Fl w Ar speed
|
||||
Set the sending speed in words per minute. If not specified the default
|
||||
speed of 20 WPM is used.
|
||||
.It Fl f Ar frequency
|
||||
Set the sidetone frequency to something other than the default 600 Hz.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fl w
|
||||
and
|
||||
.Fl f
|
||||
flags only work in conjunction with the
|
||||
.Fl p
|
||||
flag.
|
||||
.Pp
|
||||
Not all prosigns have corresponding characters. Use
|
||||
.Ql #
|
||||
for
|
||||
.Em AS ,
|
||||
.Ql @
|
||||
for
|
||||
.Em SK ,
|
||||
.Ql *
|
||||
for
|
||||
.Em VE
|
||||
and
|
||||
.Ql %
|
||||
for
|
||||
.Em BK .
|
||||
The more common prosigns are
|
||||
.Ql =
|
||||
for
|
||||
.Em BT ,
|
||||
.Ql (
|
||||
for
|
||||
.Em KN
|
||||
and
|
||||
.Ql +
|
||||
for
|
||||
.Em AR .
|
||||
.Sh FILES
|
||||
.SH HISTORY
|
||||
.Bl -tag -width /dev/speaker -compact
|
||||
.It Pa /dev/speaker
|
||||
speaker device file
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width LC_CTYPE
|
||||
.It Ev LC_CTYPE
|
||||
.It Ev LANG
|
||||
If one of these variables is set to a locale ending in
|
||||
.Ql KOI8-R ,
|
||||
characters with the high-order bit set are being interpreted as
|
||||
cyrillic characters. In all other cases, they are being interpreted
|
||||
as belonging to the
|
||||
.Ql ISO_8859-1
|
||||
character set.
|
||||
.Sh HISTORY
|
||||
Sound support added by Lyndon Nerenberg (VE7TCP/VE6BBM) <lyndon@orthanc.com>.
|
||||
.Sh BUGS
|
||||
Does only understand a few European characters (namely German and
|
||||
French), but neither Asian ones, or the continental landline code.
|
||||
.Pp
|
||||
Sends a bit slower than it should due to system overhead. Some people
|
||||
would call this a feature.
|
||||
|
@ -3,6 +3,6 @@
|
||||
PROG= morse
|
||||
NOMAN= noman
|
||||
HIDEGAME=hidegame
|
||||
CFLAGS += -DSPEAKER=\"/dev/speaker\"
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
|
@ -31,6 +31,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Taught to send *real* morse by Lyndon Nerenberg (VE7TCP/VE6BBM)
|
||||
* <lyndon@orthanc.com>
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1993\n\
|
||||
@ -43,103 +48,319 @@ static char sccsid[] = "@(#)morse.c 8.1 (Berkeley) 5/31/93";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char
|
||||
*digit[] = {
|
||||
"-----",
|
||||
".----",
|
||||
"..---",
|
||||
"...--",
|
||||
"....-",
|
||||
".....",
|
||||
"-....",
|
||||
"--...",
|
||||
"---..",
|
||||
"----.",
|
||||
},
|
||||
*alph[] = {
|
||||
".-",
|
||||
"-...",
|
||||
"-.-.",
|
||||
"-..",
|
||||
".",
|
||||
"..-.",
|
||||
"--.",
|
||||
"....",
|
||||
"..",
|
||||
".---",
|
||||
"-.-",
|
||||
".-..",
|
||||
"--",
|
||||
"-.",
|
||||
"---",
|
||||
".--.",
|
||||
"--.-",
|
||||
".-.",
|
||||
"...",
|
||||
"-",
|
||||
"..-",
|
||||
"...-",
|
||||
".--",
|
||||
"-..-",
|
||||
"-.--",
|
||||
"--..",
|
||||
#ifdef SPEAKER
|
||||
#include <machine/speaker.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
struct morsetab {
|
||||
char inchar;
|
||||
char *morse;
|
||||
};
|
||||
|
||||
static int sflag;
|
||||
static struct morsetab mtab[] = {
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
/* 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', "--..",
|
||||
|
||||
/* digits */
|
||||
|
||||
'0', "-----",
|
||||
'1', ".----",
|
||||
'2', "..---",
|
||||
'3', "...--",
|
||||
'4', "....-",
|
||||
'5', ".....",
|
||||
'6', "-....",
|
||||
'7', "--...",
|
||||
'8', "---..",
|
||||
'9', "----.",
|
||||
|
||||
/* punctuation */
|
||||
|
||||
',', "--..--",
|
||||
'.', ".-.-.-",
|
||||
'?', "..--..",
|
||||
'/', "-..-.",
|
||||
'-', "-....-",
|
||||
'=', "-...-", /* BT */
|
||||
':', "---...",
|
||||
';', "-.-.-.",
|
||||
'(', "-.--.", /* KN */
|
||||
')', "-.--.-",
|
||||
'$', "...-..-",
|
||||
'+', ".-.-.", /* AR */
|
||||
|
||||
/* prosigns without already assigned values */
|
||||
|
||||
'#', ".-...", /* AS */
|
||||
'@', "...-.-", /* SK */
|
||||
'*', "...-.", /* VE */
|
||||
'%', "-...-.-", /* BK */
|
||||
|
||||
'\0', ""
|
||||
};
|
||||
|
||||
|
||||
static struct morsetab iso8859tab[] = {
|
||||
'á', ".--.-",
|
||||
'à', ".--.-",
|
||||
'â', ".--.-",
|
||||
'ä', ".-.-",
|
||||
'ç', "-.-..",
|
||||
'é', "..-..",
|
||||
'è', "..-..",
|
||||
'ê', "-..-.",
|
||||
'ö', "---.",
|
||||
'ü', "..--",
|
||||
|
||||
'\0', ""
|
||||
};
|
||||
|
||||
static struct morsetab koi8rtab[] = {
|
||||
/*
|
||||
* the cyrillic alphabet; you'll need a KOI8R font in order
|
||||
* to see the actual characters
|
||||
*/
|
||||
'Á', ".-", /* a */
|
||||
'Â', "-...", /* be */
|
||||
'×', ".--", /* ve */
|
||||
'Ç', "--.", /* ge */
|
||||
'Ä', "-..", /* de */
|
||||
'Å', ".", /* ye */
|
||||
'Ö', "...-", /* she */
|
||||
'Ú', "--..", /* ze */
|
||||
'É', "..", /* i */
|
||||
'Ê', ".---", /* i kratkoye */
|
||||
'Ë', "-.-", /* ka */
|
||||
'Ì', ".-..", /* el */
|
||||
'Í', "--", /* em */
|
||||
'Î', "-.", /* en */
|
||||
'Ï', "---", /* o */
|
||||
'Ð', ".--.", /* pe */
|
||||
'Ò', ".-.", /* er */
|
||||
'Ó', "...", /* es */
|
||||
'Ô', "-", /* te */
|
||||
'Õ', "..-", /* u */
|
||||
'Æ', "..-.", /* ef */
|
||||
'È', "....", /* kha */
|
||||
'Ã', "-.-.", /* ce */
|
||||
'Þ', "---.", /* che */
|
||||
'Û', "----", /* sha */
|
||||
'Ý', "--.-", /* shcha */
|
||||
'Ù', "-.--", /* yi */
|
||||
'Ø', "-..-", /* myakhkij znak */
|
||||
'Ü', "..-..", /* ae */
|
||||
'À', "..--", /* yu */
|
||||
'Ñ', ".-.-", /* ya */
|
||||
|
||||
'\0', ""
|
||||
};
|
||||
|
||||
void show(const char *), play(const char *), morse(char);
|
||||
|
||||
static int pflag, sflag;
|
||||
static int wpm = 20; /* words per minute */
|
||||
#define FREQUENCY 600
|
||||
static int freq = FREQUENCY;
|
||||
|
||||
#ifdef SPEAKER
|
||||
#define DASH_LEN 3
|
||||
#define CHAR_SPACE 3
|
||||
#define WORD_SPACE (7 - CHAR_SPACE - 1)
|
||||
static float dot_clock;
|
||||
int spkr;
|
||||
tone_t sound;
|
||||
#endif
|
||||
|
||||
static struct morsetab *hightab = iso8859tab;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
register int ch;
|
||||
register char *p;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
register int ch;
|
||||
register char *p;
|
||||
|
||||
while ((ch = getopt(argc, argv, "s")) != EOF)
|
||||
switch((char)ch) {
|
||||
while ((ch = getopt(argc, argv, "spw:f:")) != EOF)
|
||||
switch ((char) ch) {
|
||||
case 'f':
|
||||
freq = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case 'w':
|
||||
wpm = atoi(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
fprintf(stderr, "usage: morse [string ...]");
|
||||
fputs("usage: morse [-s] [-p] [-w speed] [-f frequency] [string ...]\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (pflag && sflag) {
|
||||
fputs("morse: only one of -p and -s allowed\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (pflag && ((wpm < 1) || (wpm > 60))) {
|
||||
fputs("morse: insane speed\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (pflag && (freq == 0))
|
||||
freq = FREQUENCY;
|
||||
|
||||
(void)setuid(getuid());
|
||||
#ifdef SPEAKER
|
||||
if (pflag) {
|
||||
if ((spkr = open(SPEAKER, O_WRONLY, 0)) == -1) {
|
||||
perror(SPEAKER);
|
||||
exit(1);
|
||||
}
|
||||
dot_clock = wpm / 2.4; /* dots/sec */
|
||||
dot_clock = 1 / dot_clock; /* duration of a dot */
|
||||
dot_clock = dot_clock / 2; /* dot_clock runs at twice */
|
||||
/* the dot rate */
|
||||
dot_clock = dot_clock * 100; /* scale for ioctl */
|
||||
}
|
||||
#endif
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (*argv)
|
||||
if((p = getenv("LC_CTYPE")) || (p = getenv("LANG"))) {
|
||||
if(strlen(p) >= strlen("KOI8-R") &&
|
||||
strcasecmp(&p[strlen(p) - strlen("KOI8-R")], "KOI8-R") == 0)
|
||||
hightab = koi8rtab;
|
||||
setlocale(LC_CTYPE, p);
|
||||
} else {
|
||||
setlocale(LC_CTYPE, "");
|
||||
}
|
||||
|
||||
if (*argv) {
|
||||
do {
|
||||
for (p = *argv; *p; ++p)
|
||||
morse((int)*p);
|
||||
for (p = *argv; *p; ++p) {
|
||||
morse((int) *p);
|
||||
}
|
||||
morse((int) ' ');
|
||||
} while (*++argv);
|
||||
else while ((ch = getchar()) != EOF)
|
||||
morse(ch);
|
||||
} else {
|
||||
while ((ch = getchar()) != EOF)
|
||||
morse(ch);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
morse(c)
|
||||
register int c;
|
||||
void
|
||||
morse(char c)
|
||||
{
|
||||
struct morsetab *m;
|
||||
|
||||
if (isalpha(c))
|
||||
show(alph[c - (isupper(c) ? 'A' : 'a')]);
|
||||
else if (isdigit(c))
|
||||
show(digit[c - '0']);
|
||||
else if (c == ',')
|
||||
show("--..--");
|
||||
else if (c == '.')
|
||||
show(".-.-.-");
|
||||
else if (isspace(c))
|
||||
show(" ...\n");
|
||||
c = tolower(c);
|
||||
if ((c == '\r') || (c == '\n'))
|
||||
c = ' ';
|
||||
if (c == ' ') {
|
||||
if (pflag) {
|
||||
play(" ");
|
||||
return;
|
||||
} else {
|
||||
show("");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (m = ((unsigned char)c < 0x80? mtab: hightab);
|
||||
m->inchar != '\0';
|
||||
m++) {
|
||||
if (m->inchar == c) {
|
||||
if (pflag) {
|
||||
play(m->morse);
|
||||
} else
|
||||
show(m->morse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
show(s)
|
||||
register char *s;
|
||||
void
|
||||
show(const char *s)
|
||||
{
|
||||
if (sflag)
|
||||
printf(" %s", s);
|
||||
else for (; *s; ++s)
|
||||
printf(" %s", *s == '.' ? "dit" : "daw");
|
||||
printf(",\n");
|
||||
else
|
||||
for (; *s; ++s)
|
||||
printf(" %s", *s == '.' ? "dit" : "dah");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
play(const char *s)
|
||||
{
|
||||
#ifdef SPEAKER
|
||||
const char *c;
|
||||
|
||||
for (c = s; *c != '\0'; c++) {
|
||||
switch ((int) *c) {
|
||||
case '.':
|
||||
sound.frequency = freq;
|
||||
sound.duration = dot_clock;
|
||||
break;
|
||||
case '-':
|
||||
sound.frequency = freq;
|
||||
sound.duration = dot_clock * DASH_LEN;
|
||||
break;
|
||||
case ' ':
|
||||
sound.frequency = 0;
|
||||
sound.duration = dot_clock * WORD_SPACE;
|
||||
break;
|
||||
default:
|
||||
sound.duration = 0;
|
||||
}
|
||||
if (sound.duration) {
|
||||
if (ioctl(spkr, SPKRTONE, &sound) == -1) {
|
||||
perror("ioctl play");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
sound.frequency = 0;
|
||||
sound.duration = dot_clock;
|
||||
if (ioctl(spkr, SPKRTONE, &sound) == -1) {
|
||||
perror("ioctl rest");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
sound.frequency = 0;
|
||||
sound.duration = dot_clock * CHAR_SPACE;
|
||||
ioctl(spkr, SPKRTONE, &sound);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user