NetKeyer - FlexRadio CW Keyer

NetKeyer is a cross-platform GUI application for CW (Morse code) keying with FlexRadio devices, supporting both serial port and MIDI input devices.

NetKeyer - FlexRadio CW Keyer

A cross-platform GUI application for CW (Morse code) keying with FlexRadio devices, supporting both serial port and MIDI input devices.

Download

Download pre-built binaries of NetKeyer now!

Features

Requirements

Building from Source

If you don’t want to use the pre-built binaries, you can build from source directly.

cd NetKeyer
dotnet build

Running

cd NetKeyer
dotnet run

Usage

Setup Page

  1. SmartLink (Optional): Click “Enable SmartLink” to connect to remote radios via FlexRadio SmartLink
  2. Select Radio:
    • Click “Refresh” to discover FlexRadio devices
    • Select a radio and GUI client station from the dropdown, OR
    • Select “No radio (sidetone only)” for practice mode
  3. Select Input Device Type: Choose between:
    • Serial Port (HaliKey v1) - uses CTS (left) and DCD (right) pins
    • MIDI (HaliKey MIDI, CTR2) - uses configurable MIDI note mappings
  4. Choose Input Device:
    • For Serial: Select the serial port connected to your keyer/paddle
    • For MIDI: Select the MIDI device, then optionally click “Configure MIDI Notes…” to customize mappings
  5. Connect: Click “Connect” to begin operating

Operating Page

  1. Monitor Paddle Status: Visual indicators show left/right paddle state in real-time
  2. Adjust CW Settings:
    • Speed (WPM): Controls dit/dah timing
    • Sidetone: Volume of local audio feedback
    • Pitch: Frequency of sidetone tone
  3. Select Keyer Mode:
    • Iambic: Automatic dit/dah generation with Mode A or Mode B
    • Straight Key: Direct on/off control
  4. Swap Paddles: Reverse left/right paddle assignment if needed
  5. Disconnect: Return to setup page to change settings

MIDI Configuration

The MIDI note configuration dialog allows you to assign any MIDI note (0-127) to one or more functions:

Default mappings (compatible with HaliKey MIDI and CTR2):

Troubleshooting

Connection Issues

Radio not found:

GUI client binding fails:

Audio Issues

No sidetone:

High latency:

Input Device Issues

Serial port not found:

MIDI device not responding:

Debug Logging

NetKeyer supports detailed debug logging controlled by the NETKEYER_DEBUG environment variable. This can help diagnose issues with specific subsystems.

Log File Location:

Debug messages are automatically written to a log file in the NetKeyer application data folder:

You can easily access the log folder via Help → View Debug Log… in the application menu.

Note: On Windows, GUI applications don’t show console output when run outside a debugger. Debug messages are always written to the log file, making them accessible even when the console isn’t visible.

Available Debug Categories:

Category Description
keyer Iambic keyer state machine (paddle state, element timing, mode transitions)
midi MIDI input parsing and raw event processing
input Input abstraction layer (paddle state changes, indicator updates)
slice Transmit slice mode monitoring (CW vs PTT mode detection)
sidetone Audio sidetone provider (tone/silence state machine, timing)
audio Audio device management (initialization, enumeration, selection)

Usage Examples:

Linux/macOS:

# Enable all debug output
NETKEYER_DEBUG=all dotnet run

# Enable specific categories
NETKEYER_DEBUG=keyer,midi dotnet run

# Enable all MIDI-related categories using wildcard
NETKEYER_DEBUG=midi* dotnet run

Windows PowerShell:

# Enable all debug output
$env:NETKEYER_DEBUG="all"
dotnet run

# Enable specific categories
$env:NETKEYER_DEBUG="keyer,midi"
dotnet run

Windows CMD:

# Enable all debug output
set NETKEYER_DEBUG=all
dotnet run

# Enable specific categories
set NETKEYER_DEBUG=keyer,midi
dotnet run

Common Debugging Scenarios:


Developer Information

Project Structure

NetKeyer/
├── Views/                  # XAML UI layouts
├── ViewModels/             # Application logic and data binding
│   ├── MainWindowViewModel.cs
│   ├── MidiConfigDialogViewModel.cs
│   ├── AudioDeviceDialogViewModel.cs
│   └── AboutWindowViewModel.cs
├── Models/                 # Data models
│   ├── UserSettings.cs
│   ├── MidiNoteMapping.cs
│   └── AudioDeviceInfo.cs
├── Services/               # Core application services
│   ├── InputDeviceManager.cs
│   ├── KeyingController.cs
│   ├── RadioSettingsSynchronizer.cs
│   ├── SmartLinkManager.cs
│   └── TransmitSliceMonitor.cs
├── Audio/                  # Sidetone generation
│   ├── SidetoneGeneratorFactory.cs
│   └── ISidetoneGenerator.cs
│   ├── SidetoneGenerator.cs (PortAudio)
│   ├── WasapiSidetoneGenerator.cs (Windows WASAPI)
│   ├── SidetoneProvider.cs (waveform generation)
├── Midi/                   # MIDI input handling
│   └── MidiPaddleInput.cs
├── Keying/                 # Iambic keyer logic
│   └── IambicKeyer.cs
├── SmartLink/              # SmartLink authentication
│   ├── SmartLinkAuthService.cs
│   ├── SmartLinkModels.cs
├── Helpers/                # Utility classes
│   ├── DebugLogger.cs
│   └── UrlHelper.cs
├── lib/                    # Compiled FlexRadio libraries

Input Device Support

Serial Port (HaliKey v1):

MIDI Devices:

Iambic Keyer Implementation

Audio Sidetone

WASAPI Backend (Windows preferred):

PortAudio Backend:

Settings Persistence

User settings are stored in:

Stored settings include:

License

FlexLib components are Copyright © 2018-2024 FlexRadio Systems. All rights reserved.