• JavaScript 62.5%
  • Python 20.4%
  • HTML 10.9%
  • CSS 6.1%
  • Shell 0.1%
Find a file
2026-09-11 11:58:11 +00:00
deploy Add simplified Koch practice frontend and HTTPS deployment 2026-09-11 08:46:52 +00:00
web Prevent delayed audio timers from compressing Morse playback 2026-09-11 11:58:11 +00:00
.gitignore Add simplified Koch practice frontend and HTTPS deployment 2026-09-11 08:46:52 +00:00
koch.py New tool to generate random sequences of letters for Koch's method 2016-11-17 10:24:43 -08:00
LICENSE.txt Add MIT license 2021-02-22 17:01:48 -06:00
morse.py Functions to translate to morse, play and save generated audio 2016-11-16 10:07:09 -08:00
morseTable.py Add all international Morse Code symbols 2016-11-22 17:39:43 -08:00
output.mp3 Added info on converting audio formats 2016-11-16 10:39:16 -08:00
output.wav Change output file data type from float32 to int16 2016-11-16 10:38:43 -08:00
play.py Print useful Morse timing information 2016-11-17 10:24:56 -08:00
README.md Prevent delayed audio timers from compressing Morse playback 2026-09-11 11:58:11 +00:00

Simplified Morse practice frontend

The code and documentation added or modified for this fork were written by gpt-6-astra, acting as the Codex coding agent under user direction. The original upstream code is credited to cduck/morse.

Live app: Morse practice. Repository: samuel/morse-exam-prep.

Run python3 -m http.server 8000 from this directory and open http://localhost:8000/web/play.html. No build step or frontend dependencies are required.

Quick start

  1. Click a top charset button such as EI. It generates 200 practice characters by default, adds spaces using English word-length frequencies, and starts the 5-second countdown before playback.
  2. Click Pause to stop during the countdown or playback. Selecting another top charset generates a fresh message and starts a new countdown.
  3. Open Options for custom generation, navigation, Restart, and Text to play. Custom generation buttons prepare the text; press Play to start it.

On a fresh visit with no saved message, the editor is empty and Play is dimmed and disabled. Generating, entering, or loading nonblank text enables playback. Clearing the text while paused disables Play again. Clearing it during playback keeps Pause available so you can still stop the audio.

Practice controls

  • The top buttons are EI, EIA, TN, TNM, EIATNM, A-Z, 0-9, ?.-=;,, and A-Z0-9?.-=;,. Clicking one selects that charset and immediately generates practice with spaces using the configured character count. Playback starts automatically after the configured initial pause.
  • The generation status identifies the charset, for example, “Generated 200 characters using TNM.” Complete alphabet and digit sets are summarized as A-Z and 0-9, including when entered manually.
  • If a browser timer is delayed, playback continues from the next unscheduled character at normal Morse timing instead of compressing overdue tones together. A sufficiently long browser stall can still cause an audible gap.
  • Play / Pause toggles playback, including during the initial countdown and after a restart. Restart begins the message again with the full initial delay. Resuming a paused initial countdown also starts the full delay again; resuming midway through a message does not add the initial delay.
  • Options is collapsed by default. It contains Input charset, Generate with spaces, and Generate without spaces, followed immediately by Navigate to character with Restart, and the editable Text to play. The preset, character count, initial pause, audio controls, and file loading follow these controls.
  • Text to play starts empty unless a saved practice message is available. The old built-in sample message is not restored. Play is disabled and dimmed when the message is empty or whitespace-only; entering, loading, or generating text enables it. Pause remains available during playback, even if the editor is cleared.
  • Closing Options only hides the controls and editor. The text remains in use for generation, playback, and restart. Open Options to edit or view the text and character highlighting.
  • Custom charset generation ignores whitespace and duplicates, normalizes letters to uppercase, and rejects unsupported characters. Enter the actual characters for custom sets; the top A-Z and 0-9 buttons expand their ranges automatically.
  • Each page starts at 8 WPM, Farnsworth 0 (normal spacing), 700 Hz, and centered pan (0). Character count defaults to 200 and initial pause to 5 seconds. ham radio asoc india default restores these settings.

Generation and spacing

Generate with spaces is the default for all top charset presets. In Options, choose Generate with spaces or Generate without spaces for the custom charset, then press Play. For example, spaced output might look like TN MTN T NMTN; unspaced output is continuous, such as TNMTNTNMTN.

Spaced generation samples each group length independently from the observed English word-occurrence counts in Peter Norvigs Google Books analysis. It uses lengths 123, including rare long groups. Three-character groups are most common (about 20.5%); five-character groups occur about 10.7% of the time. The source distribution averages about 4.79 characters per group. These are random character groups drawn from your charset, not English words.

The configured character count excludes inserted spaces: 200 means 200 practice characters plus separators. The final group is shortened when necessary to reach that exact count, and no leading or trailing space is added. Individual sessions will vary from the source frequencies, especially for short practice texts.

Run the frontend logic checks with node --test web/play.test.cjs.

To host on GitHub Pages, publish the repository root and visit /web/play.html.


Morse code audio generation tool

This tool can either play morse code directly or save to a WAV file. It translates plain text from stdin or the command line. The tone frequency, words per minute, and Farnsworth timing are also configurable through command line arguments. It should work on Mac, Linux, and Windows but has only been tested to play audio on Mac.

The original upstream HTML5 frontend is available here.

Usage

Playing sound:

$ echo "Morse code message." |python3 play.py -f 750 --wpm 10

Create audio file:

$ echo "Morse code message." |python3 play.py -f 750 --wpm 10 -o output.wav

Output: output.wav (converted to mp3)

Translate to just . and - characters:

$ echo "Morse code message." |python3 morse.py
-- --- .-. ... .   -.-. --- -.. .   -- . ... ... .- --. . .-.-.-

Learn Morse code using Koch's method

Play a random sequence of 100 A, T, and R letters

$ ./koch.py --wpm=30 --fs=10 -l 100 "ATR"

Other audio formats

Convert to mp3 or other formats with FFmpeg:

ffmpeg -i output.wav output.mp3

Output: output.mp3

Dependencies

Server hosting

Live site: https://morse.samuelshadrach.com (Cloudflare proxy, Nginx origin). Only play.html, play.css, play.js, morse.js, and morseTable.js from web/ are deployed to /var/www/morse. The repository, tests, and credentials are not published there. The HTML references a versioned playback script URL; change that version when deploying JavaScript updates so cached clients receive them. The Nginx configuration is tracked in deploy/nginx.conf; other application paths return 404. HTTP redirects to HTTPS, except the isolated ACME challenge directory. Certbot renews the Let's Encrypt origin certificate using certbot.timer and /var/www/letsencrypt for validation. The deploy hook in deploy/reload-nginx.sh validates and reloads Nginx after renewal. Certificate private keys remain outside the repository and public web directory, under /etc/letsencrypt.