Desktop CW app for Thetis/Vail workflows with:
- live keying from
CTRLorMIDI, - sidetone generation,
- CAT/PTT control,
- local and audio-input Morse decoding.
- Open PowerShell in the project root:
cd C:\git\vail-cw-tethis
- Create and activate a virtual environment:
py -m venv .venv.\.venv\Scripts\Activate.ps1
- Install dependencies:
pip install -r requirements.txt
- Run the app:
python main.py
- In the UI, set:
Input Mode(CTRLorMIDI)Audio Output
- If using Vail MIDI hardware:
- Select
Vail MIDI Out - Press
Sync Vail - Move
WPM(it auto-syncs after changes)
- Input modes:
CTRLandMIDI(noAUTOmode). CTRLmode uses keyboard paddles:- Left Ctrl = DIT
- Right Ctrl (or AltGr-compatible mapping) = DAH
MIDImode reads paddle note events from MIDI input.- MIDI startup mode switch (
CC0=0) to force Vail hardware into MIDI mode. - Vail hardware sync (
Program Changekeyer +CC1WPM conversion). - Automatic WPM sync to Vail when WPM changes in UI (debounced).
- Sidetone output with frequency and volume controls.
- Audio-input CW detection with configurable decode frequency range.
- Decoded text panel with local/audio color separation and detachable window.
- CAT/PTT methods:
CAT,RTS,DTR,THETIS_DSP. - Persistent config in
config.json.
- Windows is recommended (global Ctrl paddle polling is Windows-specific).
- Python 3.10+.
- Dependencies from
requirements.txt: midopython-rtmidisounddevicenumpypyserialpygame
- Open a terminal in the project root.
- Run
cd C:\git\vail-cw-tethis. - Create venv:
py -m venv .venv. - Activate venv:
.\.venv\Scripts\Activate.ps1. - Upgrade pip:
python -m pip install --upgrade pip. - Install deps:
pip install -r requirements.txt. - Start app:
python main.py.
Input Mode:CTRLorMIDI.Audio Output: sidetone output device.Vail MIDI Out: MIDI output device used for Vail sync commands.Refreshupdates MIDI/audio device lists.Sync Vailsends current keyer + WPM to hardware.- In
CTRLmode, MIDI-specific controls are disabled.
Keyer Typeselector (Straight, Bug, Iambic A/B, Ultimatic, etc.).- Large WPM value display.
- Large WPM slider (
5..40 WPM). - Quick buttons:
-5,-1,+1,+5. - Additional timing controls:
Dit/Dah RatioWeightingPaddle Reverse- Every WPM change is auto-synced to Vail (when a MIDI output is selected).
- Changing
Vail MIDI OutinMIDImode also triggers auto-sync.
Decode Audio Inenables CW detection from audio input.Decode Audio Inputselects source device.Decode Range (Hz)sets detector band (Min/Max).- Status lines:
Decode AudioDecode WPM(estimated RX speed).
Sidetone OnTest SidetoneSidetone Frequency (Hz)Sidetone Volume
CAT/DSP PortCAT BaudPTT MethodThetis Key LineThetis PTT LineInvert Thetis KeyInvert Thetis PTTTX Hang Time (s)Manual PTTRelease Key
CTRL StatusPTT StatusKeyingPort StatusAudio Level
- Real-time decoded text.
Fontsize control.Clearto reset text.Detachto open a resizable detached decode window.- Audio-decoded text is shown in red for quick visual separation.
- Uses keyboard events and global key polling.
- Best supported on Windows.
- Opens MIDI input and listens for note on/off paddle events.
- Attempts output pairing for Vail sync commands.
- Startup includes mode switch command (
CC0=0). - Includes note/channel auto-mapping heuristics for common Vail note pairs.
- Manual sync: press
Sync Vail. - Auto sync: changing WPM in the UI triggers sync automatically.
- WPM conversion follows Vail Zoomer behavior:
dit_ms = 1200 / WPMCC1 = dit_ms / 2
- Set
PTT MethodtoTHETIS_DSP. - Select the correct virtual COM pair in
CAT/DSP Port. - Match
Thetis Key Line/Thetis PTT Linewith Thetis DSP-CW settings. - Use invert options if polarity is reversed.
- File:
config.json. - Saved automatically when UI values change.
- Includes mode, MIDI mapping, WPM/keyer, sidetone, decode, and CAT settings.
- If MIDI is not detected:
- Connect device before app start, then use
Refresh. - Close other apps that may lock MIDI ports.
- If MIDI keying works but sync does not:
- Verify
Vail MIDI Outis set to the hardware output port. - Check log lines after pressing
Sync Vail. - If CTRL mode does not key:
- Confirm running on Windows.
- Ensure app window receives keyboard events.
- If no sidetone:
- Check
Sidetone On, volume, output device, and system mixer output routing.