Skip to content

Add optional MIDI CW input (USB MIDI keyer support) as alternative to serial paddle input #295

Description

@ct7aup

What

Add support for CW key input via MIDI devices (USB MIDI), as an alternative to the current serial-port-based paddle input.

In this mode, AetherSDR would:

  • Open a MIDI input device
  • Listen for MIDI events
  • Map:
    • Note On → key down
    • Note Off → key up
  • Use these events to key CW transmission

This allows using external hardware keyers that already implement iambic logic and timing.

Example of such a device (tested concept):

Why

The current serial-based approach (CTS/DSR/DCD polling) works, but has some limitations:

  • Polling-based → susceptible to latency and jitter
  • Depends on USB-serial adapter behavior
  • Requires handling:
    • debounce
    • iambic timing
  • Electrical differences between adapters can cause inconsistencies

Using MIDI instead:

  • Event-driven (no polling)
  • Lower and more stable latency
  • On macOS, MIDI runs with high scheduling priority (CoreMIDI)
  • Enables use of external keyers that:
    • implement iambic A/B
    • generate precise timing in hardware

This effectively moves timing-critical CW generation out of the client, simplifying the software side.

How Other Clients Do It

  • SmartSDR for Mac uses serial control lines (RTS/CTS/DCD), but in a loopback configuration:

    • avoids GND dependency
    • improves signal reliability
  • MIDI-based input is not common in SDR clients, but widely used in:

    • DAWs
    • real-time audio systems

These systems rely on:

  • CoreMIDI (macOS)
  • ALSA MIDI (Linux)

Both provide:

  • event-driven input
  • optional timestamping
  • lower jitter than generic serial polling

Suggested Behavior

Settings

CW Input Source:
Serial (default)
MIDI

MIDI mode

When selected:

  1. List available MIDI input devices
  2. User selects one device
  3. AetherSDR listens to that device

Event mapping

MIDI Event Action
Note On (velocity > 0) Key down
Note Off Key up
Note On (velocity = 0) Key up

Interaction with CW logic

  • In MIDI mode:
    • Treat input as straight key (on/off)
    • Disable internal paddle/iambic processing
  • External device is responsible for:
    • iambic mode
    • timing
    • debouncing

Optional (future)

  • Filter by:
    • MIDI channel
    • note number
  • Separate MIDI note for PTT

Protocol Hints

No changes expected on FlexLib side.

Existing TX/CW control should be reused:

  • trigger TX on key down
  • release TX on key up

So this is purely an input layer change.

Implementation Notes

Architecture

class CWInput {
public:
virtual void start() = 0;
std::function<void(bool)> onKey;
};

Implementations:

  • SerialCWInput (existing)
  • MidiCWInput (new)

macOS

Use CoreMIDI:

  • MIDIClientCreate
  • MIDIInputPortCreate
  • callback with MIDIPacketList

Linux

Options:

  • ALSA sequencer (snd_seq_*)
  • or RtMidi (simpler cross-platform abstraction)

Summary

  • Adds a modern, low-latency CW input path
  • Keeps full backward compatibility
  • Enables use of external hardware keyers
  • Simplifies timing handling inside AetherSDR

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions