Skip to content

CW decoder and transmitter #2815

Description

@KN3M

Request preparation

  • I used an AI assistant to help structure this request
  • I checked for existing issues covering the same feature

What would you like?

IMPORTANT — before doing anything else, fetch the complete list of open
issues by reading pages sequentially until you get fewer than 100 results:
Page 1: https://github.com/aethersdr/AetherSDR/issues?state=open&per_page=100&page=1
Page 2: https://github.com/aethersdr/AetherSDR/issues?state=open&per_page=100&page=2
... continue until a page returns fewer than 100 issues.
Do NOT rely on cached or training data for the issue list.

Also fetch CLAUDE.md fresh (do not use cached versions):
https://raw.githubusercontent.com/aethersdr/AetherSDR/main/CLAUDE.md

I want to report an issue or request a feature for AetherSDR, a Linux-native
Qt6/C++20 client for FlexRadio transceivers. It uses the FlexLib API over TCP/UDP.

DUPLICATE CHECK — this is mandatory. Search the fetched issue list for keywords
related to my description below. Check titles AND bodies. If you find an existing
issue that covers the same thing, STOP and tell me:

Duplicate found: # — <title>
I recommend adding a +1 reaction and a comment describing your use case.
Do NOT write a new issue if a duplicate exists.

If no duplicate exists, determine whether my description is a BUG REPORT or a
FEATURE REQUEST, then write a GitHub issue using the appropriate format below.
Use GitHub-flavored Markdown formatting (headers, code blocks, bullet points).

FOR FEATURE REQUESTS include:

  1. A clear, concise title (imperative mood)
  2. What — what the feature does from the user's perspective

  3. Why — what problem it solves

  4. How Other Clients Do It — how SmartSDR, GQRX, SDR++, etc. handle this

  5. Suggested Behavior — specific UX: what the user clicks, sees, what happens.

    Reference AetherSDR UI elements (AppletPanel, VfoWidget, RxApplet, etc.)
  6. Protocol Hints — relevant FlexLib commands, or "Unknown — needs research"

  7. Acceptance Criteria — 3-5 bullet points defining done vs not-done

FOR BUG REPORTS include:

  1. A clear title describing the broken behavior
  2. What happened — describe the incorrect behavior

  3. What I expected — describe the correct behavior

  4. Steps to reproduce — numbered steps to trigger the bug

  5. Environment — OS, radio model, firmware version if relevant

  6. Suggested fix — if you have an idea what's wrong, describe it

Suggest appropriate labels from: enhancement, bug, audio, GUI, spectrum,
protocol, external devices, upstream, SmartLink, windows, macOS

Here is my idea or bug report:

[Describe your feature or bug here in plain English]
Got it! You want a CW (Morse code) reader/decoder and a Transmit helper integrated with AetherSDR for FlexRadio. I can guide you through a practical approach, because these aren’t simple one-line setups—they usually involve scripting or configuring external helpers that talk to AetherSDR via its API. Here’s a thorough plan:


1. CW Reader (Decoder)

AetherSDR doesn’t natively decode CW into text, but it supports CAT/ExtIO control and audio output, which we can feed to a CW decoder. Options:

Option A: Use CW Skimmer style decoding

  1. Route the AetherSDR audio output to a CW decoding program (like Fldigi or CW Skimmer).
  2. Set the audio output in AetherSDR to a virtual audio cable (VAC).
  3. Configure Fldigi to read that audio stream and decode CW.

Option B: Python CW Decoder

You can use Python with numpy and scipy to do a basic CW reader:

  • Capture audio from AetherSDR (via WAV or live audio stream).
  • Apply FFT and envelope detection to detect Morse code tones.
  • Translate tone timings into dots and dashes, then into text.

Example outline (pseudo-Python):

import numpy as np
import sounddevice as sd

FS = 48000  # Audio sample rate
DURATION = 10  # seconds to read

def detect_cw(audio):
    # Simple envelope detection
    envelope = np.abs(np.hilbert(audio))
    threshold = np.mean(envelope) * 2
    cw_signal = envelope > threshold
    return cw_signal

audio = sd.rec(int(FS * DURATION), samplerate=FS, channels=1)
sd.wait()
cw_signal = detect_cw(audio.flatten())
# Process cw_signal to extract dots/dashes

This can then be mapped to Morse code sequences.


2. Transmit (CW / SSB / Digital) from AetherSDR

AetherSDR can send audio or IQ data to FlexRadio via the Flex API or ExtIO. For CW:

  1. CW Keyer Script (Python)

    • Generate a sine wave at the desired CW frequency.
    • Key it on/off according to dot/dash timing.
    • Send it to AetherSDR’s transmit audio output or FlexRadio via API.

Example CW transmitter outline (pseudo-Python):

import numpy as np
import sounddevice as sd
import time

FS = 48000  # sample rate
FREQ = 700  # CW tone frequency
WPM = 20    # words per minute

dot_length = 1.2 / WPM  # seconds

def morse_wave(message):
    # Map letters to Morse
    morse_code = {'A': '.-', 'B': '-...', ...}
    audio = np.array([])
    t = np.linspace(0, dot_length, int(FS*dot_length), False)
    tone = np.sin(2*np.pi*FREQ*t)
    
    for char in message.upper():
        if char in morse_code:
            for sym in morse_code[char]:
                if sym == '.':
                    audio = np.concatenate((audio, tone))
                else:
                    audio = np.concatenate((audio, tone*3))
                audio = np.concatenate((audio, np.zeros(int(FS*dot_length))))  # space between dots/dashes
            audio = np.concatenate((audio, np.zeros(int(FS*dot_length*3))))  # space between letters
    return audio

message = "TEST"
audio_data = morse_wave(message)
sd.play(audio_data, FS)
sd.wait()
  1. Connect to FlexRadio:

    • Use the FlexLib API to send the audio/IQ stream directly to the transmit channel.
    • Alternatively, use virtual audio routing (VAC or Soundflower) if you don’t want direct API coding.

✅ Summary of Workflow

  1. Receive CW:

    • Audio from AetherSDR → Virtual audio → CW decoder (Fldigi / Python)
  2. Transmit CW:

    • Morse → Tone generator → Audio → AetherSDR / FlexRadio transmit

This setup is fully programmable and gives you automation for CW reading and transmitting.


If you want, I can write a ready-to-run Python script that:

  • Listens to AetherSDR audio
  • Decodes CW in real-time
  • Generates CW transmit signals for FlexRadio

It would be a self-contained CW reader + transmitter.

Do you want me to do that next?

Metadata

Metadata

Assignees

Labels

CWCW keying, decode, and operationGUIUser interfaceenhancementImprovement to existing featuremaintainer-reviewRequires maintainer review before any action is takenquestionFurther information is requested

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