Skip to main content

Overview

Transmit mode (--tx) converts data from standard input into FSK (Frequency-Shift Keying) audio tones. minimodem reads data byte-by-byte and modulates it into audio signals that can be played through speakers, written to audio files, or transmitted over radio.

Basic Transmit Usage

1

Specify transmit mode

Use the --tx flag to enable transmit mode:
minimodem --tx 1200
2

Provide input data

Data is read from standard input. You can pipe data or type interactively:
echo "Hello World" | minimodem --tx 1200
3

Audio output

By default, audio is played through your system’s default audio device in real-time.

Command-Line Options

The transmit mode is activated using any of these equivalent flags:
minimodem --transmit 1200

Interactive Transmission

When transmitting to a real-time audio device (not a file), minimodem operates in interactive mode:
minimodem --tx 300
# Type your message and press Enter
# Each keystroke is transmitted in real-time

Interactive Mode Features

Leader Tone

Transmits 2 bits of mark tone before data to establish carrier

Trailer Tone

Transmits 2 bits of mark tone after data to complete transmission

Idle Carrier

Emits mark tone during input pauses (1/25 second timeout)

Auto Flush

Adds 0.5 seconds of silence to flush audio buffers

Transmit Workflow

Here’s how minimodem processes data in transmit mode (from src/minimodem.c:114-250):
1

Read input

Reads data byte-by-byte from stdin using read() system call
2

Encode data bits

Converts each byte to data bits using the configured encoder (ASCII, Baudot, etc.)
3

Add framing

Wraps data bits with start bits and stop bits according to the protocol
4

Generate tones

  • Mark frequency (logical 1): Higher frequency tone
  • Space frequency (logical 0): Lower frequency tone
  • Each bit is transmitted for exactly 1/baud_rate seconds
5

Output audio

Writes audio samples to the audio backend (speakers or file)

Practical Examples

Text Transmission

echo "HELLO" | minimodem --tx 1200
Transmits at 1200 baud using Bell 202 encoding:
  • Mark: 1200 Hz
  • Space: 2200 Hz
  • 8 data bits + 1 start + 1 stop

Binary Data Transmission

Transmit binary files by piping them directly:
# Transmit a small binary file
cat data.bin | minimodem --tx 1200

# Compress and transmit
gzip -c file.txt | minimodem --tx 1200

# Transmit with Base64 encoding for reliability
base64 file.bin | minimodem --tx 1200

Custom Frequencies

Override the default mark and space frequencies:
# Custom frequencies for 1200 baud
echo "TEST" | minimodem --tx 1200 \
  --mark 1200 \
  --space 2400

# Inverted frequencies (space > mark)
echo "TEST" | minimodem --tx 1200 --inverted

Volume Control

Adjust transmission amplitude:
# Half volume
echo "HELLO" | minimodem --tx 1200 --volume 0.5

# Quarter volume
echo "HELLO" | minimodem --tx 1200 -v 0.25

# Very quiet (useful for testing)
echo "HELLO" | minimodem --tx 1200 -v 0.1
Volume Range: The --volume parameter accepts values from 0.0 to 1.0, where 1.0 is full amplitude. Values greater than 1.0 may cause clipping and distortion.

Advanced Transmit Options

Custom Frame Format

Modify the data frame structure:
# No start or stop bits (NOAA SAME format)
echo "TEST" | minimodem --tx 1200 \
  --startbits 0 \
  --stopbits 0

# Two stop bits (TDD/TTY format)
echo "TEST" | minimodem --tx tdd

# 1.5 stop bits (RTTY format)
echo "TEST" | minimodem --tx rtty

Sync Bytes

Add synchronization bytes at the start of transmission:
# NOAA SAME format with sync byte 0xAB
echo "ZCZC-WXR-RWT-012345+0015-0321234-STATION-" | \
  minimodem --tx same

# Custom sync byte (16 sync bytes transmitted)
echo "DATA" | minimodem --tx 1200 --sync-byte 0x55

Continuous Carrier

Keep the carrier tone active even when idle:
# Useful for radio transmission
minimodem --tx 300 --tx-carrier < input.txt
The --tx-carrier option prevents the carrier from dropping during input pauses, maintaining a constant presence for radio applications where rapid carrier on/off switching is undesirable.

Sample Rate Control

Change the audio sample rate:
# 48 kHz (default)
echo "TEST" | minimodem --tx 1200 --samplerate 48000

# 44.1 kHz (CD quality)
echo "TEST" | minimodem --tx 1200 -R 44100

# 8 kHz (narrow bandwidth)
echo "TEST" | minimodem --tx 1200 -R 8000

Technical Details

Tone Generation

minimodem uses a sine wave lookup table (LUT) for efficient tone generation (src/minimodem.c:979):
// Initialize with 4096-entry sine table at full amplitude
simpleaudio_tone_init(tx_sin_table_len, tx_amplitude);
Performance: The default LUT size of 4096 entries provides excellent quality with minimal CPU usage. Larger tables use more memory but don’t significantly improve quality.

Frame Transmission

Each data byte is transmitted as a frame with this structure:
1

Start bits

Transmitted as space frequency (or mark if --invert-start-stop)
  • Default: 1 start bit
  • Duration: 1/baud_rate seconds per bit
2

Data bits

Transmitted LSB-first (unless --msb-first specified)
  • 5 bits for Baudot
  • 7 or 8 bits for ASCII
  • Custom bit counts supported
3

Stop bits

Transmitted as mark frequency (or space if --invert-start-stop)
  • Default: 1 stop bit
  • Can be fractional (e.g., 1.5 or 2.0)

Timing Accuracy

Bit timing is calculated as (src/minimodem.c:132):
size_t bit_nsamples = sample_rate / data_rate + 0.5f;
For 1200 baud at 48000 Hz:
  • Samples per bit: 48000 / 1200 = 40 samples
  • Bit duration: 40 / 48000 = 0.833 ms

Troubleshooting

  • Check volume: minimodem --tx 1200 --volume 1.0
  • Verify audio device: minimodem --tx 1200 --alsa=hw:0,0
  • Test with file output: minimodem --tx 1200 --file test.wav
  • Reduce volume: --volume 0.5
  • Check sample rate compatibility
  • Ensure CPU is not overloaded (shouldn’t be an issue with minimodem)
  • Verify stdin has data: echo "TEST" | minimodem --tx 1200
  • Check for EOT marker: minimodem --tx 1200 --print-eot
  • Enable quiet mode to reduce stderr noise: minimodem --tx 1200 --quiet
  • Explicitly set frequencies: --mark 1200 --space 2200
  • Verify baud mode: minimodem --tx 1200 not minimodem --tx 300
  • Check for frequency inversion: remove --inverted if present

See Also

Build docs developers (and LLMs) love