[net.ham-radio] code practice pgms for your terminal

mkg (11/13/82)

In doing some house cleaning, I found these programs that are supposed to
produce morse code using input text or a file.  Somebody gave them to me about
two years ago and they have been collecting dust in my uucp directory since.

These programs use the audible bell in your terminal and produce morse code.
I am told that if the duration of the bell is right, running these programs
at 300 baud produces respectable CW.

I hate to throw these away so I am posting them to the net in hopes
that somebody out there can use them for code practice, reading rotated
jokes, or what ever.
   Marsh Gosnell AD2H   BTL Piscataway  harpo!whuxlb!mkg


/* echo CW using input from keyboard */
#define MAXDAH 25
#define MAXDIT 25
#define MAXICB 25
#define MAXIWB 50

#define B 0007
#define F 0177

char dit[MAXDIT];
char dah[MAXDAH];
char icb[MAXICB];
char iwb[MAXIWB];

struct WPM{
	int dahl;
	int pazl;
	int icbl;
	int iwbl;
	char *nwpm;
};
struct WPM wpm[20]={
	5,7,2,6,"11.5",
	5,7,4,3,"11",
	5,7,5,6,"10.5",
	5,7,6,10,"10",
	5,7,8,9,"9.5",
	5,7,9,15,"9",
	5,7,10,22,"8.5",
	7,7,11,22,"8",
	7,8,10,24,"7.5",
	8,8,12,24,"7",
	9,8,14,31,"6.5",
	9,9,16,30,"6",
	9,10,17,34,"5.5",
	10,10,22,40,"5"
};

char *pps[]={
	"-.--.-","-.--.-","","",   /* ( ) * + */
	"--..--","",".-.-.-","-..-.",   /* , - . / */
	"-----",".----","..---","...--",   /* 0 1 2 3 */
	"....-",".....","-....","--...",   /* 4 5 6 7 */
	"---..","----.","---...","-.-.-.",   /* 8 9 : ; */
	"","","","..--..",   /* < = > ? */
	"",".-","-...","-.-.",   /* @ 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 */
};

main(argc,argv)
int argc;
char *argv[];
{
	int c,r;
	int n,i,j;
	int x;
	int ss;

	/* decode */

	*++argv;
	for (i=0;i<14;i++)
	{
		if ((n=strcmp(*argv,wpm[i].nwpm)) == 0) break;
	}
	if (i == 14)
	{
		printf("usage: code wpm\n");
		printf("standard input contains text to send\n");
		printf("wpm=[5 to 11.5] in steps of .5\n");
		exit(0);
	}
	else
		sound(wpm[i].dahl,wpm[i].pazl,wpm[i].icbl,wpm[i].iwbl);

	for (;;)
	{
		ss=0;
		if ((c=getchar()) == 0) break;

		if (c == '_')
		{
			ss=1;
			if ((c=getchar()) == 0) break;
		}
		if (c==' ' || c=='\n')
		{
			printf("%s",iwb);
			continue;
		}
		if (c>='a' && c<='z') {
			c=c+'A'-'a';
		}

		if (c>='(' && c<='Z')
		{
			x=c-'(';
			for (j=0;(c=pps[x][j]);j++)
			{
				if (c==' ') continue;
				if (c=='.')
					printf("%s",dit);
				else
					printf("%s",dah);
			}
			if (ss == 0) printf("%s",icb);
		}
	}
}
sound(ldah,lpas,licb,liwb)
int ldah,lpas,licb,liwb;
{
	int i;
	if (lpas+1 >= MAXDIT || lpas+ldah >= MAXDAH ||
	    licb >= MAXICB || liwb >= MAXIWB )
	{
		printf("length exceeds max\n");
		return(0);
	}
	dit[0]=B;
	for (i=1;i<=lpas;i++)
	{
		dit[i]=F;
	}
	dit[lpas+1]=0;
	for (i=0;i<=ldah;i++)
	{
		dah[i]=B;
	}
	for (i=ldah;i<=ldah+lpas;i++)
	{
		dah[i]=F;
	}
	dah[ldah+lpas]=0;
	for (i=0;i<=licb;i++)
	{
		icb[i]=F;
	}
	icb[licb]=0;
	for (i=0;i<=liwb;i++)
	{
		iwb[i]=F;
	}
	iwb[liwb]=0;
	return(0);
}
atoi(s)  /* convert s (a string of intergers to intergers */
char s[];
{
	int i,n;

	n=0;
	for (i=0; s[i]>='0' && s[i]<='9'; ++i)
		n=10*n+s[i]-'0';
	return(n);
}
strcmp(s,t)
char s[],t[];
{
	int i;
	i=0;
	while (s[i] == t[i])
		if (s[i++] == '\0')
			return(0);
	return(s[i]-t[i]);
}


/* echo CW using input file */
#define MAXDAH 25
#define MAXDIT 25
#define MAXICB 25
#define MAXIWB 50

#define B 0007
#define F 0177

#include <stdio.h>

struct WPM{
	int dahl;
	int pazl;
	int icbl;
	int iwbl;
	char *nwpm;
};
struct WPM wpm[20]={
	0,0,0,0,"0",
	5,7,2,6,"11.5",
	5,7,4,3,"11",
	5,7,5,6,"10.5",
	5,7,6,10,"10",
	5,7,8,9,"9.5",
	5,7,9,15,"9",
	5,7,10,22,"8.5",
	7,7,11,22,"8",
	7,8,10,24,"7.5",
	8,8,12,24,"7",
	9,8,14,31,"6.5",
	9,9,16,30,"6",
	9,10,17,34,"5.5",
	10,10,22,40,"5",
	10,12,23,45,"4.5"
};

int mt[6400],ma[6400],mac[6400];
int stack[100],sp;
char dit[MAXDIT];
char dah[MAXDAH];
char icb[MAXICB];
char iwb[MAXIWB];
char *pps[]={
	"-.--.-","-.--.-","","",   /* ( ) * + */
	"--..--","",".-.-.-","-..-.",   /* , - . / */
	"-----",".----","..---","...--",   /* 0 1 2 3 */
	"....-",".....","-....","--...",   /* 4 5 6 7 */
	"---..","----.","---...","-.-.-.",   /* 8 9 : ; */
	"","","","..--..",   /* < = > ? */
	"",".-","-...","-.-.",   /* @ 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 */
};

main(argc,argv)
int argc;
char *argv[];
{
	int hi,lo,cu,x,c,r;
	int ti,i,j,k;
	char test[100],ans[100];
	char testi[100];

	FILE *fp, *fopen();

	/* decode */

	if (argc==1)
	{
		printf("usage: test.morse 'file name'\n");
		exit(0);
	}
	if ((fp=fopen(*++argv,"r"))==NULL)
	{
		printf("can't open file %s\n",*argv);
		exit(1);
	}

	hi=16;
	lo=0;
	cu=8;
	r=100;

	for (;;)
	{
		ti=i=0;
		for (;;)
		{
			if ((c=getc(fp)) == EOF)
			{
				fclose(fp);
				break;
			}

			if (c=='\n') break;

			testi[ti]=c;
			ti++;
			if (c>='A' && c<='Z') c=c+'a'-'A';
			if (c!=' ')
			{
				test[i]=c;
				++i;
			}
		}

		if (i==0) exit(0);

		do
		{
			if (r>=90 || r<=50)
			{
				printf ("test speed is %s wpm\n",wpm[cu].nwpm);
				sound(wpm[cu].dahl,wpm[cu].pazl,wpm[cu].icbl,wpm[cu].iwbl);
			}
			for (k=0;k<ti;k++)
			{
				c=testi[k];
				if (c==' ')
				{
					printf("%s",iwb);
					continue;
				}
				if (c>='a' && c<='z') c=c+'A'-'a';
				if (c>='(' && c<='Z')
				{
					x=c-'(';
					for (j=0;(c=pps[x][j]);j++)
					{
						if (c=='.') printf("%s",dit);
						else printf("%s",dah);
					}
					printf("%s",icb);

				}
			}

			j=0;
			while ((r=getchar()) != '\n')
			{
				if (r != ' ')
				{
					ans[j]=r;
					++j;
				}
			}

			if (j==0) r=0;
			else r=grade(test,i,ans,j);
			printf("you scored %d correct out of %d in %d answers\n",r,i,j);
			testi[ti]=0;
			r=r*100;
			r=r/i;

			if (r>50) printf("The correct answer was:\n%s\n",testi);

			if (r<=50)
			{
				if (cu==lo)
				{
					++cu;
					hi=lo=cu;
				}
				else
				{
					lo=cu;
					cu=cu+(hi-lo)/2;
				}
			}

			if (r>=90)
			{
				if (cu==hi)
				{
					--cu;
					hi=lo=cu;
				}
				else
				{
					hi=cu;
					cu=cu-(hi-lo)/2;
				}
			}

			if (cu>15) cu=15;
			if (cu<1) cu=1;
		} while (r<=50);
	}
}
sound(ldah,lpas,licb,liwb)
int ldah,lpas,licb,liwb;
{
	int i;
	if (lpas+1 >= MAXDIT || lpas+ldah >= MAXDAH ||
	    licb >= MAXICB || liwb >= MAXIWB )
	{
		printf("length exceeds max\n");
		return(0);
	}
	dit[0]=B;
	for (i=1;i<=lpas;i++)
	{
		dit[i]=F;
	}
	dit[lpas+1]=0;
	for (i=0;i<=ldah;i++)
	{
		dah[i]=B;
	}
	for (i=ldah;i<=ldah+lpas;i++)
	{
		dah[i]=F;
	}
	dah[ldah+lpas]=0;
	for (i=0;i<=licb;i++)
	{
		icb[i]=F;
	}
	icb[licb]=0;
	for (i=0;i<=liwb;i++)
	{
		iwb[i]=F;
	}
	iwb[liwb]=0;
	return(0);
}
grade(tlist,ml,alist,al)
char tlist[],alist[];
int ml,al;
{
	int lm;
	int i,j;
	int ac,max;
	lm=0;
	for (i=0;i<al;i++)
	{
		for (j=0;j<ml;j++)
		{
			if (tlist[j]==alist[i])
			{
				mt[lm]=j;
				ma[lm]=i;
				mac[lm]=0;
				if (lm>6400)
				{
					printf("match list length exceeded \n");
					return(0);
				}
				++lm;
			}
		}
	}
	max=0;
	if (lm==1)
	{
		max=1;
		return(max);
	}
	for (i=0;i<lm-1;i++)
	{
		if (mac[i]==0)
		{
			sp=0;
			stack[sp]=i;
			for (j=i+1;j<lm;j++)
			{
				if (mt[j]>mt[stack[sp]] &&
				    ma[j]>ma[stack[sp]])
				{
					++sp;
					stack[sp]=j;
				}
			}
			ac=0;
			while (sp>=0)
			{
				j=stack[sp];
				--sp;
				++ac;
				mac[j]=ac;
			}
			if (ac>max) max=ac;
		}
	}
	return(max);
}