Skip to content

EasierLu/ATCP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ATCP — Audio Transmission Control Protocol

Language Build License

中文 | English

ATCP is a pure C99, zero-dependency audio-channel data communication protocol stack library. It establishes a bidirectional data link between a PC and an MCU over a standard 3.5 mm audio interface (Speaker Out / Mic In), enabling covert communication that bypasses the network layer.

┌─────────────────┐      3.5mm Audio Cable      ┌─────────────────┐
│    Host (PC)    │ ◄─────────────────────────► │   Device (MCU)  │
│                 │   Speaker Out ──► ADC In    │                 │
│                 │   Mic In     ◄── DAC Out    │                 │
└─────────────────┘                             └─────────────────┘

Features

  • Zero Dependencies — Pure C99; embeddable on any platform (bare-metal / RTOS / desktop)
  • Bidirectional — Downlink: differential stereo OFDM + adaptive QAM (QPSK–256-QAM); Uplink: mono fixed QPSK
  • Dual Reliability — Reed-Solomon FEC + sliding-window ARQ with selective retransmission, AIMD congestion window, and RTT-based adaptive timeout
  • Adaptive Rate — Real-time SNR-driven QAM order switching (automatic up/down-grade) with peer notification via rate-change frames
  • Auto Reconnect & Self-Healing — Heartbeat-based disconnection detection, exponential-backoff reconnection, and runtime modulation fallback on link degradation
  • High Throughput — ~90% effective data ratio in streaming mode; up to ~95 kbps downlink
  • Optimized Hot Path — Precomputed FFT twiddle tables and QAM constellation lookup tables; cached training waveforms
  • Adaptive Handshake — 4-phase negotiation of sample rate, QAM order, etc., with real link-quality (SNR) assessment and automatic fallback
  • Non-blocking API — Event-driven design; all operations are asynchronous
  • Cross-platform — Windows / Linux / STM32 / ESP32 and more

Protocol Architecture

┌───────────────────────────────┐
│     Application Layer         │  User code (file transfer, command control, encryption, etc.)
├───────────────────────────────┤
│     Link Layer                │  Handshake, heartbeat/auto-reconnect, framing, ARQ (AIMD + adaptive timeout)
├───────────────────────────────┤
│     Coding Layer              │  RS FEC encoding/decoding, CRC32 checksum
├───────────────────────────────┤
│     Modulation Layer          │  OFDM + M-QAM, frame sync, channel estimation
├───────────────────────────────┤
│     Physical Layer            │  Differential signaling, AGC, CFO/SFO compensation
└───────────────────────────────┘

Building

Prerequisites

  • CMake >= 3.10
  • C99-compatible compiler (MSVC / GCC / Clang)

Compilation

# Shared library (default)
cmake -B build
cmake --build build --config Release

# Static library (recommended for embedded)
cmake -B build -DBUILD_SHARED_LIBS=OFF
cmake --build build --config Release
CMake Option Default Description
BUILD_SHARED_LIBS ON ON = shared library, OFF = static library
BUILD_TESTS ON Whether to build unit tests

Static library users should define ATCP_STATIC in their compile options to suppress DLL export decorations.

Quick Start

#include <atcp/atcp.h>

/* 1. Implement platform callbacks */
int my_audio_write(const float *samples, int n, int ch, void *ud) { /* write to speaker */ return n; }
int my_audio_read(float *samples, int n, int ch, void *ud)        { /* read from mic */   return n; }
uint32_t my_get_time_ms(void *ud)                                  { return get_system_time_ms(); }

int main(void) {
    /* 2. Configure platform callbacks */
    atcp_platform_t platform = {0};
    platform.audio_write = my_audio_write;
    platform.audio_read  = my_audio_read;
    platform.get_time_ms = my_get_time_ms;

    /* 3. Create instance (NULL = use default config) */
    atcp_instance_t *inst = atcp_create(NULL, &platform);

    /* 4. Initiate connection */
    atcp_connect(inst);

    /* 5. Main loop (recommended 10-15 ms interval) */
    while (1) {
        atcp_tick(inst);

        if (atcp_get_state(inst) == ATCP_STATE_CONNECTED) {
            const uint8_t msg[] = "Hello MCU!";
            atcp_send(inst, msg, sizeof(msg));

            uint8_t buf[256];
            size_t received = 0;
            if (atcp_recv(inst, buf, sizeof(buf), &received) == ATCP_OK) {
                /* process received data */
            }
        }
    }

    atcp_destroy(inst);
    return 0;
}

API Overview

Function Description
atcp_create(config, platform) Create an instance; pass NULL for config to use defaults
atcp_destroy(inst) Destroy instance and release all resources
atcp_connect(inst) Initiate connection (active side), non-blocking
atcp_accept(inst) Wait for connection (passive side), non-blocking
atcp_disconnect(inst) Disconnect
atcp_send(inst, data, len) Send data, non-blocking
atcp_recv(inst, buf, len, &received) Receive data
atcp_tick(inst) Drive the protocol stack (audio I/O, frame sync, demodulation, ARQ, heartbeat)
atcp_get_state(inst) Get current connection state (incl. ATCP_STATE_RECONNECTING)
atcp_get_stats(inst) Get statistics (BER, SNR, throughput, RTT, reconnect count, link quality, etc.)
atcp_get_link_quality(inst) Get composite link-quality score (0–100)
atcp_reset(inst) Reset instance back to IDLE (reconnectable without destroy/recreate)
atcp_get_audio_buf_size(inst) Get required audio buffer size (number of floats)

Project Structure

ATCP/
├── CMakeLists.txt                 # Top-level build config
├── lib/                           # Core C protocol stack library
│   ├── CMakeLists.txt             # Library build config
│   ├── USER_GUIDE.md              # User guide
│   ├── DEVELOPER_GUIDE.md         # Developer guide
│   ├── include/atcp/              # Public headers
│   │   ├── atcp.h                 #   Unified API entry point
│   │   ├── types.h                #   Type definitions, status codes
│   │   ├── config.h               #   Configuration struct & defaults
│   │   └── platform.h             #   Platform abstraction callbacks
│   ├── src/
│   │   ├── atcp.c                 # API implementation (integration layer)
│   │   ├── common/                # FFT, complex math, ring buffer, PRNG
│   │   ├── physical/              # Differential coding, AGC, CFO/SFO compensation
│   │   ├── modulation/            # OFDM, QAM, training sequences, frame sync, channel estimation
│   │   ├── coding/                # RS FEC, CRC32, GF(256)
│   │   └── link/                  # Framing, handshake, ARQ, ACK, heartbeat
│   └── tests/                     # Unit tests & integration tests
└── simulator/                     # C# simulator + WPF control center
    ├── ATCP.Simulator.sln         # Visual Studio solution
    ├── SimCommon/                 # Shared lib: P/Invoke, TCP audio transport, channel model,
    │                             #   reusable engines, PRBS/FFT, cross-process telemetry
    ├── SimControlCenter/          # WPF unified control center (GUI)
    ├── SimUpper/                  # Host simulator (console, reuses engine)
    ├── SimMiddleware/             # Relay + channel-impairment injection
    └── SimLower/                  # Device simulator (console, reuses engine)

Platform Porting

Using ATCP requires implementing three callbacks in atcp_platform_t:

Callback Description
audio_write Write audio samples to the output device (Speaker / DAC)
audio_read Read audio samples from the input device (Mic / ADC)
get_time_ms Return current system time in milliseconds
Platform audio_write / audio_read get_time_ms
Windows WASAPI / PortAudio GetTickCount()
Linux ALSA / PulseAudio clock_gettime()
STM32 DMA + DAC/ADC HAL_GetTick()
ESP32 I2S Driver esp_timer_get_time() / 1000

Simulator

ATCP includes a C# simulation suite that emulates the audio channel over TCP, enabling protocol-stack validation and channel-impairment experiments without real hardware. It ships with a WPF unified control center (GUI) alongside the standalone console tools.

Component Description
SimControlCenter WPF unified control center. Three tabs: Link Monitor (state / signal strength / RTT / throughput / BER / link quality with live charts), Channel Simulation (live impairment sliders + waveform & spectrum), Performance Test (PRBS + SNR sweep, CSV export). Hosts the middleware in-process and launches host/device as isolated child processes.
SimUpper Host simulator — initiates connection, sends/receives data (text-echo or PRBS mode)
SimMiddleware Relay + channel-impairment injection between host and device
SimLower Device simulator — accepts connection, echo / PRBS verification
SimCommon Shared library — P/Invoke wrappers, TCP audio transport, reusable engines, channel model, PRBS/FFT, cross-process telemetry

Channel-impairment model (SimMiddleware, live-tunable)

The middleware interprets the byte stream as float32 audio waveforms and applies a configurable physical-layer channel:

  • AWGN — target-SNR-driven Gaussian noise
  • Multipath / frequency-selective fading — configurable tapped-delay-line FIR
  • Slow fading — Rayleigh / Rician envelope (Doppler / K-factor)
  • Phase noise & clock jitter — fractional-delay resampling (ppm / σ°)
  • Amplitude distortion — tanh soft-clip + gain + DC offset
  • AGC — ported from agc.c (attack/release peak tracking)
  • High-precision oversampling — 1/2/4× internal processing
  • Presets: Clean / MildIndoor / UrbanMultipath / Harsh

Running

# 1. Build the core library first (produces atcp.dll)
cmake -B build && cmake --build build --config Release

# 2. Build the simulator suite
dotnet build simulator/ATCP.Simulator.sln -c Release

# 3a. GUI: run SimControlCenter and click Start
#     (hosts the middleware in-process, launches SimUpper/SimLower as child processes)

# 3b. Or run the three consoles separately (start middleware first):
#     SimMiddleware [--preset=Clean|MildIndoor|UrbanMultipath|Harsh] [--snr=<dB>]
#     SimUpper [host] [--prbs]
#     SimLower [host] [--prbs]

Note: The ATCP core is single-instance / single-process by design (e.g. a global FFT plan), so the GUI runs the host and device as separate processes and hosts the impairment-free middleware in-process for visualization. The simulator depends on atcp.dll; build the core library first.

Documentation

  • User Guide — Build steps, full API reference, configuration parameters
  • Developer Guide — Architecture design, module details, coding standards, extension guide

License

See the LICENSE file.

About

Audio Transmission Control Protocol

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages