Skip to content

iontodirel/libmodem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

202 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libmodem

NOTE: libmodem is a work in progress, the implementation is not yet complete

A(FSK) modem library for APRS and packet radio.

libmodem provides a reusable platform for experimenting with AFSK/FSK modulation and demodulation, and for building and evaluating new demodulators.

libmodem includes the components needed to implement a complete software modem: AX.25 and FX.25 bitstream encode/decode, an audio interface with support for WASAPI, ALSA, and Core Audio, I/O routines for communication over sockets and serial ports, and a collection of modulators and demodulators.

The library is designed to be modular: you can swap bitstream encoders, audio interfaces, modulators, and demodulators to configure different pipelines. Components are intentionally loosely coupled so pieces can be reused independently, down to small functions.

libmodem is cross platform and is supported natively on Windows, Linux and OSX. The build system and code is seamless to integrate on all platforms.

libmodem is fully testable, and is very extensivly tested, with thousands of lines of test code and over 50 tests, including FFTs for frequency accuracy, using Direwolf to test the modulator, and using the WA8LMF TNC Test CDs and Direwolf generated bitstreams.

A complete, end to end reference modem implementation is included, with support for 300, 1200, 2400, and 9600 bps operation and AX.25 plus FX.25 framing. The modem is configured as a composable pipeline: modulators and demodulators are wired to named audio streams, data streams, and PTT streams, and each stage can be swapped independently.

The configuration supports many to many routing. A single modulator can transmit to multiple audio outputs at the same time, for example a live sound card and a WAV renderer, while ingesting packets from multiple inputs such as TCP, serial, stdin, or built in test sources. Audio streams can be shared across pipelines and reused as many times as needed. The audio layer supports native devices (WASAPI and ALSA), TCP audio transport with separate audio and control ports, WAV input and output for repeatable testing, and null or synthetic audio sources for demos and validation.

On the data side, the modem can expose multiple interfaces concurrently, including multi client TCP servers, serial KISS, stdout, rotating log and JSON file streams, and an external dynamic library interface for custom integration. Output formats are selectable per stream and can be mixed across consumers, including KISS, TNC2 style text, JSON, AX.25 hex or binary, raw bitstream, and telemetry augmented variants where supported. This makes it easy to do workflows like writing decoded bitstreams to disk for analysis, streaming decoded frames to multiple clients, or generating synthetic traffic using random and repeat packet sources.

Transmit control is equally flexible. PTT can be driven over serial using RTS or DTR with configurable polarity, via GPIO on platforms like Raspberry Pi with optional pre and post delays, or through a plugin library so you can integrate with custom keying hardware. Modulator parameters such as mark and space frequencies, TX delay and tail, gain, preemphasis, and leading and trailing silence are all configurable, and the same base modulator can be cloned and specialized via inheritance for variants like a WAV only renderer or a multi output transmitter.

Features

  • Modulator
    • Support for AFSK and FSK modulation
    • Supported baud rates: 300, 1200, 2400, and 9600
    • Coherent modulation
    • Modulator interface enables swappable modulators and extensibility
  • Audio interface
    • Support for native Windows, Linux and OSX audio: WASAPI, ALSA, and Core Audio
    • Sound over TCP/IP is supported for both capture/render with separate audio and control ports
      • Control port can be used to control the volume over a TCP interface
    • WAV file input and output streams
    • Null and synthetic audio sources for demos, validation, and stress testing
    • Modem can automatically control volume level
    • Extensibility allows for seamless integration of new audio interfaces into the modem
  • PTT
    • Serial PTT via RTS or DTR with configurable polarity
    • GPIO PTT support with configurable pin numbering and optional pre and post delays on Raspberry Pi platforms
    • External plugin library PTT interface for custom keying hardware
      • Enables hamlib or PTT control over CAT
    • TCP PTT control
  • Formatting
    • Supports AX.25, FX.25 and IL2P encoding and decoding
  • Pipeline
    • Pluggable pipeline design where bitstream encoders, audio interfaces, modulators, and demodulators can be swapped independently
    • Data stream support for multiple concurrent interfaces
      • Multi client TCP servers with arbitrary number of clients
      • Serial interface
      • stdin and stdout data streams
      • Rotating log streams and rotating JSON file streams with size and flush policies
      • External dynamic library data stream interface for custom integrations
    • Multiple selectable data formats per stream
      • KISS, TNC2 text, APRS text, APRS JSON, AX.25 hex, AX.25 binary, raw bitstream, telemetry streams
      • Telemetry augmented variants for supported formats
    • Rich async event system that can be used to render UI or used by loggers
  • Loggers
    • Log the sound bitstream, frames and packets to log files with configurable rotation and flush policies
  • Configurable from a single JSON configuration file
    • JSON file support comments, and inheritance of configurations
  • Cross platform support with native Windows, Linux, and macOS builds

Goals

  • Modular library-first design for experimenting with AFSK and FSK modulation and demodulation and for building and evaluating new demodulators
  • Readability, reuse and simplicity even at the cost of some code duplication
  • Core building blocks for a complete software modem, including AX.25 and FX.25 bitstream encode and decode
  • Full testability with test suite with 70 plus tests, including FFT based frequency checks and Direwolf and WA8LMF validation
  • Complete end to end reference modem implementation with support for 300, 1200, 2400, and 9600 bps operation and AX.25 plus FX.25 framing
  • State of the art demulator for 1200 bps AFSK based on the WA8LMF TNC Test CD benchmark

Development

Building

The project uses CMake as the build system, and supports native builds on Windows, Linux, and macOS. The code is written in modern C++

Run the install_dependencies script on your host platform.

Open the root directory in VSCode or Visual Studio and set the modem directory as the configure directory.

Dependencies

Most depedencies are installed and managed automatically by CMake, using FetchContent.

Only the following dependencies are managed externally and have to be installed by a script or manually by the developer. Use install_dependencies.sh, install_dependencies.zsh, or install_dependencies.ps1 to install these dependencies on Linux, OSX and Windows.

  • libudev, on Linux only.
  • libasound2, on Linux only.
  • Direwolf, on Linux/OSX only. It's automatically acquired by CMake on Windows. Used only by the tests.
  • Python3. Used only by the tests.
    • numpy
    • scipy

Complete list of dependencies:

  • libmodem
    • libcorrect for Reed-Solomon coding
    • libudev on Linux for audio device mapping and enumeration
    • libasound2 on Linux for ALSA audio support
    • nlohmann JSON for configuration file parsing
    • Boost for Networking and asynchronous IO
    • fmt for string formatting
    • sndfile for WAV file input and output
    • ftxui for textual UI
  • modem
    • cxxopts for command line parsing
  • tests
    • Google Test for unit testing
    • Direwolf for modulator validation
    • Python3 for test scripts and FFT validation
      • numpy for FFT validation
      • scipy for FFT validation

Development Dependencies

Install a C++ toolchain with C++20 support, CMake, Ninja for the development dependencies.

On Windows, install the Visual Studio or the Build Tools with the Desktop development with C++ workload, and select the latest MSVC v143 or v145 toolset.

On Linux, use the install_dependencies.sh script to install the dependencies and development tools.

Runtime Dependencies

  • Windows
    • The modem executable has no runtime dependencies
  • Linux
    • The modem executable depends on libudev and libasound2

Project Structure

  • libmodem - The library code, builds a static library with all the core modem functionality
  • modem - A reference modem application built on top of the library
  • tests - Test code for the project, builds an executable that runs the test suite

Source Structure

  • bitstream.h/bitstream.cpp - Bitstream encoding and decoding including AX.25 and FX.25. Contains all the routines needed to encode an APRS packet or a AX.25 frame into a bistream, or decode a bitstream into a AX.25 frame or APRS packet.
    • Contains all bitstream manipulation routines including NRZI encoding/decoding, bit stuffing/unstuffing, CRC calculation and verification, and AX.25 address field encoding/decoding, FX.25 Reed-Solomon encoding/decoding.
    • Supports bit by bit processing for streaming operation.
    • libcorrect is used for Reed-Solomon coding.
    • Customizable packet type support, allowing the same packet type to be used among different libraries.
    • Has no coupling to other code in the project.
  • audio_stream.h/audio_stream.cpp - Audio interface layer with support for WASAPI, ALSA, Core Audio, TCP audio transport, and WAV input and output
    • Abstract audio stream interface with pluggable backends.
    • Supports capture and render streams.
    • Supports volume control.
    • Support both mono and interleaved audio formats for read and write, enabling multi channel audio devices.
    • Supports audio device enumeration and identification.
    • Linux: Supports enumeration and independent control of all mixer controls
    • Windows:
      • Supports MMCSS for low latency audio processing
      • Producer/consumer threading model for audio processing
      • Uses event based buffer handling for efficient and low latency audio
    • WAV
      • Cross-platform WAV file read and write support
      • Single channel support only
    • Audio streams can be shared across pipelines and reused as needed.
  • io.h/io.cpp - I/O routines for PTT control
    • Serial port support with configurable baud rate, data bits, stop bits, parity, and flow control
    • Serial port over TCP with server and client support
  • device_description.h/device_description.cpp - Device identification for mapping logical endpoints (audio devices / serial ports) to the underlying physical hardware.
    • Properties: VID/PID/REV, manufacturer/product strings, USB serial number, OS identifiers (instance/container IDs or sysfs paths), bus/address, major/minor numbers, topology depth describing where the device sits in the USB tree.
    • Mapping capabilities:
      • Find "sibling" audio endpoints that share a common upstream hub at a configurable depth
      • Resolve a device_description back to matching audio_device instances for round-tripping between physical identity and enumerated endpoints.
  • kiss.h/kiss.cpp - KISS framing utilities for transporting AX.25 frames over a byte stream (serial/TCP/etc.).
    • KISS frame encode/decode state machine with FEND, FESC, TFEND, TFESC for escaping/unescaping.
    • Byte by byte embedded friendly encoding and decoding support.

About

A(FSK) modem library for APRS and packet radio

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages