diff --git a/README b/README deleted file mode 100644 index 1f82ff7..0000000 --- a/README +++ /dev/null @@ -1,11 +0,0 @@ -Information about this program can be found on the distribution site: - - http://c2.com/morse - -This version is by: - - Jim Wilson and others - -Based on original work by: - - Ward Cunningham diff --git a/README.md b/README.md new file mode 100644 index 0000000..a49e08a --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +## Info + +Information about this program can be found on the distribution site: + + http://c2.com/morse + +This version is by: + + Jim Wilson and others + +Based on original work by: + + Ward Cunningham + +## Build + +2022-02-12 - It builds fine in Fedora 35. No actual info for MacOS or Windows + +### Fedora 35 + +Install dependencies (package names in Fedora 35) + +* SDL2-devel fluid fltk-devel fltk-fluid + +Build + +`make` + +## Run + +Just execute `m` from terminal or drag somewhere. + diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..bd1a5ea --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,7 @@ +Morse.app/ +*.pyc +*.o +m.cxx +m.h +m +*~ diff --git a/src/Codebox.cxx b/src/Codebox.cxx index 073c687..31db3e7 100644 --- a/src/Codebox.cxx +++ b/src/Codebox.cxx @@ -119,7 +119,7 @@ int Codebox::handle(int event) { // Called by FLTK when user twitches * moved to the end of the line, and the character is inserted there. */ void Codebox::append(int c) { // Append character to displayed line - char s[] = { c, '\0' }; // A 1-char string version of c. + char s[] = { (char) c, '\0' }; // A 1-char string version of c. if (size() >= maximum_size()) // If no room for character, cut(0,1); // discard one off left side position(maximum_size()); // Return to right end of buffer diff --git a/src/Cw.cxx b/src/Cw.cxx index 0bcc574..e0a8021 100644 --- a/src/Cw.cxx +++ b/src/Cw.cxx @@ -123,6 +123,9 @@ static int need; // Nonzero to change freq/wpm/loudness static double amplitude; // New sinewave amplitude static double speed; // New speed (wpm) static double freq; // New (actual!) tone frequency (Hz) +static int doramp=0; +static int rampsize=20; // length of ramp up/down in samples +static int dotsamplecnt=0; static union { // Sinewave buffer (enough for one cycle) Uint8* c; // As char*, (required by waveget) @@ -186,6 +189,7 @@ static bool fill_cb() { * in cycles of the new frequency. */ dot = int(round(1.2*freq/speed)); // Number of cycles in one code element + doramp=rampsize; // start a ramp up immediately, at worst case we ramp up silence return true; } @@ -243,17 +247,47 @@ bool set_cw(double wpm, double freq, double loudness) { * make any frequency, speed or loudness changes while it sleeps. */ void waveget(void*, Uint8* destination, int n) { + Sint16* sdata=(Sint16*)data; + Sint16* sdataend=(Sint16*)dataend; + Sint16* sdestination=(Sint16*)destination; + Sint16 sample; + // SDL probably always ask for multiple of whole (16bit) sample + // so this loop processes 16bit samples now + n>>=1; // yes. i calculate half kingdom by shifting teh bits + int rampdownpos=(sdataend-buffer.s)*dot-rampsize; while (n--) { // Loop to copy waveform data: - *destination++ = shift&1? *data: 0; // Schlepp tone (or silence) - if (++data < dataend) continue; // Structured taboo! (much clearer!) - data = buffer.c; cycles++; // Buffer wrap? Reset, count cycle + sample = shift&1 ? *sdata : 0; + if (doramp>0) { + sample = sample*(rampsize-doramp)/rampsize; + doramp--; + } else if (doramp<0) { + sample = -sample*(doramp)/rampsize; + doramp++; + } + *sdestination++ = sample; // Schlepp tone (or silence) + if (dotsamplecnt==rampdownpos) { + if ((shift&1) && !(shift&2)) { + // start ramp down here + doramp=-rampsize; + } + } + dotsamplecnt++; + if (++sdata < sdataend) continue; // Structured taboo! (much clearer!) + sdata = buffer.s; cycles++; // Buffer wrap? Reset, count cycle Morse|shift? (idle = 0): idle++; // Pending stuff => not idle if (cycles < dot) continue; // See what I mean? We're whittling! + dotsamplecnt=0; + unsigned prevshift=shift; cycles = 0; shift >>= 1; // If element done, get next one. + if (!(prevshift&1) && (((shift>1) && (shift&1)) || ((shift<=1) && (Morse&1)))) { + // start ramp up here + doramp=rampsize; + } if (shift > 1) continue; // More character? whittle rest. shift = Morse; // Exhausted this? Get next if (Morse != 5) Morse = 0; // Not didididi... make way for more } + data=(Uint8*)sdata; if (need && !(shift&1)) fill_cb(); // If silent, make change now. } diff --git a/src/Cw.h b/src/Cw.h index 21d4576..d044ead 100644 --- a/src/Cw.h +++ b/src/Cw.h @@ -25,8 +25,8 @@ extern "C" { // This lets Pyrex find our functions /*** Cw.h - promises made to cw.cxx clients * * Cw.cxx exposes three functions. - * - * The first function, set_cw() is used to initialize the sound system, + * + * The first function, set_cw() is used to initialize the sound system, * the character codespeed, sinewave frequency and loudness. * * The second function accepts an ASCII or Unicode character (negated @@ -38,10 +38,10 @@ extern "C" { // This lets Pyrex find our functions * swallowed up the last audible peep. If this value is zero, code * is being sent. */ -bool set_cw(double WPM = 20, // Words/minute (default 20) - double freq = 1000, // Note (default 1Khz) +bool set_cw(double WPM = 22, // Words/minute (default 20) + double freq = 800, // Note (default 1Khz) double loudness = 1.0); // Loudness (default Maximum) - + bool send_cw(int ASCII); // Send character in Morse Code double idle_cw(); // Seconds we've not been sending diff --git a/src/Makefile b/src/Makefile index 4b4c5e2..b1ac819 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,23 +1,29 @@ -# "make" for MacOSX +.DEFAULT_GOAL := m + +FLTK_LIBS=`fltk-config --ldflags` +FLTK_FLAGS=`fltk-config --cxxflags` +SDL2_LIBS=`sdl2-config --libs` +SDL2_FLAGS=`sdl2-config --cflags` + +###################################################### +# MacOSX # To compile on MacOSX I used 10.6 with XCode dev tools and then -# used MacPorts to install fltk 1.1.7 and libsdl 1.2.13 -FLTK_LIBS=`fltk-config --ldstaticflags` -SDL_LIBS=`sdl-config --static-libs` +# used MacPorts to install fltk 1.1.7 and libsdl 1.2.13 CC=g++ CFLGAGS= # This may need to be changed for you. These are the X11 libraries used by # ftlk or sdl -DYLIB=/opt/local/lib/libX11.6.dylib /opt/local/lib/libXext.6.dylib /opt/local/lib/libXrandr.2.dylib /opt/local/lib/libXrender.1.dylib /opt/local/lib/libxcb.1.dylib /opt/local/lib/libXau.6.dylib /opt/local/lib/libXdmcp.6.dylib - +DYLIB=/opt/X11/lib/libX11.6.dylib /opt/X11/lib/libXext.6.dylib /opt/X11/lib/libXrandr.2.dylib /opt/X11/lib/libXrender.1.dylib /opt/X11/lib/libxcb.1.dylib /opt/X11/lib/libXau.6.dylib /opt/X11/lib/libXdmcp.6.dylib Morse.app: Bargraph.o Codebox.o Cw.o Knob.o Help.h m.o Info.plist + rm -rf Morse.app mkdir -p Morse.app/Contents/MacOS mkdir Morse.app/Contents/plugins mkdir Morse.app/Contents/Resources cp $(DYLIB) Morse.app/Contents/plugins $(CC) $(CFLAGS) -o Morse m.o Bargraph.o Codebox.o Cw.o Knob.o \ $(FLTK_LIBS) \ - $(SDL_LIBS) \ + `pkg-config --cflags --libs sdl` \ -framework Carbon mv Morse Morse.app/Contents/MacOS/ cp Info.plist Morse.app/Contents/info.plist @@ -29,49 +35,52 @@ Morse.app: Bargraph.o Codebox.o Cw.o Knob.o Help.h m.o Info.plist install_name_tool -change $$j @executable_path/../plugins/`basename $$j` Morse.app/Contents/plugins/`basename $$i`; \ done; \ done +###################################################### -# For some reason, xmake is required to make m.tgz. -m.tgz: m m.exe - rm -f m.tgz - tar czvf m.tgz * - # Use "xmake" to generate m.exe m.exe: m.fl Bargraph.o Codebox.o Cw.cxx Cw.h Knob.cxx Knob.h Help.h m.o g++ -c -Os -I/usr/local/include/SDL Cw.cxx g++ -om.exe m.o Bargraph.o Codebox.o Cw.o Knob.o \ - -static `fltk-config --ldstaticflags` \ - -lSDL -lmingw32 -lmingwex -lwinmm -lSDLmain + $(FLTK_LIBS) \ + $(SDL2_LIBS) \ + -lSDL -lmingw32 -lmingwex -lwinmm -lSDLmain strip m.exe rm *.o m.cxx m.h +###################################################### # Regular "make" is what you want for the Linux version m: m.fl Bargraph.o Codebox.o Cw.o Knob.o Help.h m.o - g++ -static -om m.o Bargraph.o Codebox.o Cw.o Knob.o \ - `sdl-config --static-libs` \ - `fltk-config --ldstaticflags` -ldl + g++ -om m.o Bargraph.o Codebox.o Cw.o Knob.o \ + $(SDL2_LIBS) \ + $(FLTK_LIBS) -ldl strip m rm *.o m.cxx m.h m.cxx: m.fl fluid -c m.fl m.o: m.cxx m.h - g++ -c -Os `fltk-config --cxxflags` m.cxx + g++ -c -Os $(FLTK_FLAGS) m.cxx Bargraph.o: Bargraph.cxx Bargraph.h - g++ -c -Os `fltk-config --cxxflags` Bargraph.cxx + g++ -c -Os $(FLTK_FLAGS) Bargraph.cxx Codebox.o: Codebox.cxx Codebox.h - g++ -c -Os `fltk-config --cxxflags` Codebox.cxx + g++ -c -Os $(FLTK_FLAGS) Codebox.cxx Knob.o: Knob.cxx Knob.h - g++ -c -Os `fltk-config --cxxflags` Knob.cxx + g++ -c -Os $(FLTK_FLAGS) Knob.cxx Cw.o: Cw.cxx Cw.h - g++ -c -Os `sdl-config --cflags` Cw.cxx + g++ -c -Os $(SDL2_FLAGS) Cw.cxx # Besemer's Python extension version cw.so: cw.pyx Cw.cxx Cw.h pyrexc cw.pyx gcc -c -fPIC -I/usr/include/python2.5 cw.c - gcc -c -fPIC `sdl-config --cflags` Cw.cxx - g++ -shared cw.o Cw.o -static `sdl-config --static-libs` -ocw.so + gcc -c -fPIC $(SDL2_FLAGS) Cw.cxx + g++ -shared cw.o Cw.o -static $(SDL2_LIBS) -ocw.so rm cw.c *.o Help.h: m.htm ./help.py Help.h + +clean: + rm -rf ./Morse.app m.cxx m.h *.o + +.PHONY: clean diff --git a/src/help.py b/src/help.py index 910a3e7..f1be83d 100755 --- a/src/help.py +++ b/src/help.py @@ -31,13 +31,13 @@ from sys import stdin -print "/* DO NOT EDIT! The following declaration and its initializer are" -print " * generated from the original HTML file by the script, help.py." -print " */\n" +print( "/* DO NOT EDIT! The following declaration and its initializer are") +print( " * generated from the original HTML file by the script, help.py.") +print( " */\n") -print "static char* HelpString =" +print( "static const char* HelpString =" ) for helpline in stdin: - print ' "'+helpline.replace('"','\\"').rstrip()+'\\n"' -print ';' + print( ' "'+helpline.replace('"','\\"').rstrip()+'\\n"') +print( ';' ) diff --git a/src/m.fl b/src/m.fl index 76d8ab6..9573da1 100644 --- a/src/m.fl +++ b/src/m.fl @@ -1,6 +1,6 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0105 -header_name {.h} +version 1.0105 +header_name {.h} code_name {.cxx} decl {/* Copyright 1998-2004 Ward Cunningham and Jim Wilson @@ -23,25 +23,25 @@ decl {/* along with Morse; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */} {public -} +} -decl {\#include "Bargraph.h"} {} +decl {\#include "Bargraph.h"} {} -decl {\#include "Codebox.h"} {} +decl {\#include "Codebox.h"} {} decl {\#include "Knob.h"} {public -} +} -decl {\#include "Cw.h"} {} +decl {\#include "Cw.h"} {} -decl {\#include } {} +decl {\#include } {} -decl {\#include "Help.h"} {} +decl {\#include "Help.h"} {} Function {adjust(Fl_Widget*, void*)} {private return_type void } { code {set_cw(Speed->value(), Tone->value(), 1.0);} {} -} +} Function {full_screen(bool fs)} {private } { @@ -52,7 +52,7 @@ if (fs) { W = Morse->w(); H = Morse->h(); Morse->fullscreen(); } else Morse->fullscreen_off(X,Y,W,H);} {} -} +} Function {} {open } { @@ -153,17 +153,17 @@ smaller->activate();} Fl_Roller Speed { label Speed callback adjust - tooltip {Words per minute} xywh {385 0 80 25} type Horizontal align 8 minimum 10 maximum 30 step 0.5 value 20 + tooltip {Words per minute} xywh {385 0 80 25} type Horizontal align 8 minimum 10 maximum 30 step 0.5 value 22 class Knob } Fl_Roller Tone { label Tone callback adjust - tooltip {Adjust tone frequency} xywh {520 0 80 25} type Horizontal align 8 minimum 440 maximum 2000 step 50 value 1000 + tooltip {Adjust tone frequency} xywh {520 0 80 25} type Horizontal align 8 minimum 440 maximum 2000 step 50 value 800 class Knob } Fl_Group Lesson { - label {Q7ZG098O1JPW.LRAM6B/XD=YCKN23?FU45VHSITE} open + label {Q7ZG098O1JPW.LRAM6B/XD=YCKN23?FU45$VHSITE} open private tooltip {Click the white box, below, to start.} xywh {0 25 640 185} box UP_BOX align 5 resizable code0 {o->disable("./=?");} code1 {o->activate("Q7ZG");} @@ -199,7 +199,7 @@ Lesson->redraw();} } menuitem {} { label Symbols - callback {const char* syms = "./=?"; + callback {const char* syms = "./=?$"; if (o->mvalue()->value()) Lesson->enable(syms); else @@ -238,4 +238,4 @@ while (1) { Lesson->grade(c , pass); // Update scores Lesson->graduate(); // Maybe add a letter }} {} -} +}