Skip to content

bcc1010/EchoMesh

Repository files navigation

EchoMesh

EchoMesh Logo

An offline-first acoustic mesh network that transmits data over sound

This project was built at IC Hack 2026. For motivation, see our Devpost page.


Overview

EchoMesh is a peer-to-peer mesh network application that enables communication between devices using sound waves instead of traditional wireless protocols. Using the ggwave library, messages are encoded into audio frequencies and transmitted through device speakers, then received and decoded by nearby device microphones.

This enables communication in scenarios where:

  • No internet or cellular connectivity is available
  • Radio silence is required (no RF emissions)
  • Quick ad-hoc networks need to be established
  • Short-range, line-of-sight communication is sufficient

Features

  • Data-Over-Sound Transmission — Send and receive messages using acoustic signals
  • Automatic Mesh Relay — Messages automatically hop through intermediate nodes to reach their destination
  • Voice Input — Speak your message using speech recognition
  • Text-to-Speech — Incoming messages are read aloud with a preparation countdown for relay
  • Real-time Statistics — Track sent, received, relayed, and dropped messages
  • Deduplication — Smart packet tracking prevents message loops in the mesh
  • Broadcast & Direct Messaging — Send to everyone (ALL) or specific callsigns
  • Persistent State — Callsign and settings survive page refreshes
  • Responsive Design — Works on desktop and mobile browsers

How It Works

  1. An emergency needs to be reported to a destination that is not directly accessible without a middleman relaying the message.
  2. Initial sender types or uses speech to text to input text.
  3. Text is converted into a waveform transmission using multi-frequency frequency-shift keying (FSK). The bit rate is 16/bytes per second (equivalent to speaking at 192 wpm). Transmissions have a header and a body:
    • The header identifies the sender, receiver and also has time to live (the number of hops before the message is discarded).
    • The body contains the message.
  4. Using the first device's speaker the transmission is played into the walkie-talkie.
  5. Nearby walkie-talkies receive and play the transmission into their corresponding device's microphone.
  6. The app interprets the transmission and decides what to do next depending on the header of the message.
    • If our current receiver is the intended recipient (identified in the header) then the transmission chain is terminated.
    • If the time to live reaches 0 the message is discarded.
    • If either of these conditions is not met, the message is relayed with a decremented time to live.
  7. If the intended recipient receives the transmission, it is interpreted and the text body is read out using text to speech.

Packet Structure

Messages are transmitted as compact packets with the following format:

uid8|from|dest|ttl|body
Field Description
uid8 8-character unique identifier for deduplication
from Sender's callsign
dest Destination callsign or ALL for broadcast
ttl Time-to-live (hop count remaining)
body Message content

Mesh Relay Logic

  1. Receive — When a packet is received, it's checked against seen messages
  2. Deduplicate — If already seen, the packet is dropped to prevent loops
  3. Accept — If the message is for this node (or broadcast), it's displayed
  4. Relay — If TTL > 0 and message needs forwarding, a countdown begins
  5. Transmit — After the countdown (and TTS), the packet is relayed with decremented TTL

Audio Protocol

  • Sample Rate: 48,000 Hz
  • Protocol: DT_FASTEST (optimized for speed)
  • Max Packet Size: 140 bytes
  • Volume: 100% for reliable transmission

Getting Started

Prerequisites

  • Node.js 18+
  • A modern browser with Web Audio API support (Chrome, Firefox, Edge, Safari)
  • Microphone access permission

Installation

# Clone the repository
git clone https://github.com/yourusername/echomesh.git
cd echomesh

# Install dependencies
npm install

# Start development server
npm run dev

The app will be available at http://localhost:5173 (and on your local network if using --host).

Building for Production

npm run build
npm run preview

Usage

Basic Operation

  1. Set Your Callsign — Enter a unique identifier in the callsign field (e.g., ALPHA, BASE1)
  2. Start Listening — Click the "START LISTENING" button to begin receiving messages
  3. Send a Message — Type a message and click "SEND" or press Enter

Sending Messages

  • Broadcast: Leave destination as ALL to send to everyone in range
  • Direct Message: Enter a specific callsign (e.g., BRAVO) to send to that node only
  • Voice Input: Click the microphone button to speak your message

Receiving & Relaying

When a message arrives:

  1. A purple banner appears while the message is read aloud (TTS)
  2. If relaying is needed, a yellow countdown banner appears
  3. Position your device near a walkie-talkie or other relay device during countdown
  4. The message is automatically retransmitted after the countdown

Status Indicators

Color Meaning
Green border Ready / Idle
Purple border TTS speaking or voice input active
Yellow border Relay countdown in progress
Orange border Receiving audio
Blue border Transmitting audio

Tech Stack

  • React 19 — UI framework
  • TypeScript — Type-safe JavaScript
  • Vite — Fast build tool and dev server
  • Tailwind CSS v4 — Utility-first styling
  • Zustand — Lightweight state management
  • ggwave — Data-over-sound encoding/decoding (WASM)
  • Web Audio API — Audio capture and playback
  • Web Speech API — Text-to-speech and speech recognition

Architecture

src/
├── App.tsx              # Main UI component
├── store.ts             # Zustand state management
├── types.d.ts           # TypeScript type definitions
└── hooks/
    ├── useAudioModem.ts      # ggwave TX/RX logic
    ├── useTextToSpeech.ts    # TTS functionality
    └── useSpeechRecognition.ts # Voice input

Configuration

Key constants in the codebase:

Constant Value Location
MAX_PACKET_SIZE 140 bytes App.tsx
RELAY_DELAY 2000ms useAudioModem.ts
DEFAULT_TTL 3 hops store.ts
SAMPLE_RATE 48000 Hz useAudioModem.ts

Browser Compatibility

Browser TX RX TTS Voice Input
Chrome Yes Yes Yes Yes
Firefox Yes Yes Yes Limited
Safari Yes Yes Yes Yes
Edge Yes Yes Yes Yes

Note: HTTPS is required for microphone access on most browsers.

License

MIT License — see LICENSE for details.

Acknowledgments

  • ggwave by Georgi Gerganov for the incredible data-over-sound library
  • Built at IC Hack 2026

About

ICHack 2026

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors