• Stars
    star
    1,496
  • Rank 30,152 (Top 0.7 %)
  • Language
    C++
  • License
    MIT License
  • Created over 3 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Tiny data-over-sound library

ggwave

Actions Status License: MIT ggwave badge pypi npm

Tiny data-over-sound library.

Click on the images below to hear what it sounds like:

waver-v1.4.0.mp4

talking-buttons-demo-0.mp4
arduino-tx-3-github.mp4

Details

This library allows you to communicate small amounts of data between air-gapped devices using sound. It implements a simple FSK-based transmission protocol that can be easily integrated in various projects. The bandwidth rate is between 8-16 bytes/sec depending on the protocol parameters. Error correction codes (ECC) are used to improve demodulation robustness.

This library is used only to generate and analyze the RAW waveforms that are played and captured from your audio devices (speakers, microphones, etc.). You are free to use any audio backend (e.g. PulseAudio, ALSA, etc.) as long as you provide callbacks for queuing and dequeuing audio samples.

Here is a list of possible applications of ggwave with a few examples:

Try it out

You can easily test the library using the free waver application which is available on the following platforms:

Download on the App Store Get it on Google Play Get it from the Snap Store

Browser demos

HTTP service

# audible example
curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello%20world!' --output hello.wav

# ultrasound example
curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello%20world!&p=4' --output hello.wav

Technical details

Below is a short summary of the modulation and demodulation algorithm used in ggwave for encoding and decoding data into sound.

Modulation (Tx)

The current approach uses a multi-frequency Frequency-Shift Keying (FSK) modulation scheme. The data to be transmitted is first split into 4-bit chunks. At each moment of time, 3 bytes are transmitted using 6 tones - one tone for each 4-bit chunk. The 6 tones are emitted in a 4.5kHz range divided in 96 equally-spaced frequencies:

Freq, [Hz] Value, [bits] Freq, [Hz] Value, [bits] ... Freq, [Hz] Value, [bits]
F0 + 00*dF Chunk 0: 0000 F0 + 16*dF Chunk 1: 0000 ... F0 + 80*dF Chunk 5: 0000
F0 + 01*dF Chunk 0: 0001 F0 + 17*dF Chunk 1: 0001 ... F0 + 81*dF Chunk 5: 0001
F0 + 02*dF Chunk 0: 0010 F0 + 18*dF Chunk 1: 0010 ... F0 + 82*dF Chunk 5: 0010
... ... ... ... ... ... ...
F0 + 14*dF Chunk 0: 1110 F0 + 30*dF Chunk 1: 1110 ... F0 + 94*dF Chunk 5: 1110
F0 + 15*dF Chunk 0: 1111 F0 + 31*dF Chunk 1: 1111 ... F0 + 95*dF Chunk 5: 1111

For all protocols: dF = 46.875 Hz. For non-ultrasonic protocols: F0 = 1875.000 Hz. For ultrasonic protocols: F0 = 15000.000 Hz.

The original data is encoded using Reed-Solomon error codes. The number of ECC bytes is determined based on the length of the original data. The encoded data is the one being transmitted.

Demodulation (Rx)

Beginning and ending of the transmission are marked with special sound markers (#13). The receiver listens for these markers and records the in-between sound data. The recorded data is then Fourier transformed to obtain a frequency spectrum. The detected frequencies are decoded back to binary data in the same way they were encoded.

Reed-Solomon decoding is finally performed to obtain the original data.

Examples

The examples folder contains several sample applications of the library:

Example Description Audio
ggwave-rx Very basic receive-only program SDL
ggwave-cli Command line tool for sending/receiving data through sound SDL
ggwave-wasm WebAssembly module for web applications SDL
ggwave-to-file Output a generated waveform to an uncompressed WAV file -
ggwave-from-file Decode a waveform from an uncompressed WAV file -
waver GUI application for sending/receiving data through sound SDL
ggwave-py Python examples PortAudio
ggwave-js Javascript example Web Audio API
spectrogram Spectrogram tool SDL
ggweb-spike Android example using a WebView to wrap ggwave into a simple app WebAudio
buttons Record and send commands via Talking buttons Web Audio API
r2t2 Transmit data through the PC speaker PC speaker
ggwave-objc Minimal Objective-C iOS app using ggwave AudioToolbox
ggwave-java Minimal Java Android app using ggwave android.media
ggwave-fm Transmit ggwave messages with HackRF Radio
esp32-rx Transmit and receive messages using ESP32 -
rp2040-rx Transmit and receive messages using Raspberry Pi Pico (RP2040) -
arduino-rx Transmit and receive messages using Arduino RP2040 -
arduino-tx Transmit messages using Arduino Uno -
arduino-rx-web Receive messages from Arduino Uno Web Audio API

Other projects using ggwave or one of its prototypes:

  • wave-gui - a GUI for exploring different modulation protocols
  • wave-share - WebRTC file sharing with sound signaling

Building

Dependencies for SDL-based examples

[Ubuntu]
$ sudo apt install libsdl2-dev

[Mac OS with brew]
$ brew install sdl2

[MSYS2]
$ pacman -S git cmake make mingw-w64-x86_64-dlfcn mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2

Linux, Mac, Windows (MSYS2)

# build
git clone https://github.com/ggerganov/ggwave --recursive
cd ggwave && mkdir build && cd build
cmake ..
make

# running
./bin/ggwave-cli

Emscripten

git clone https://github.com/ggerganov/ggwave --recursive
cd ggwave
mkdir build && cd build
emcmake cmake ..
make

Python

pip install ggwave

More info: https://pypi.org/project/ggwave/

Node.js

npm install ggwave

More info: https://www.npmjs.com/package/ggwave

iOS

Available as a Swift Package: https://github.com/ggerganov/ggwave-spm

Installing the Waver application

Get it from the Snap Store

Linux

sudo snap install waver
sudo snap connect waver:audio-record :audio-record

Mac OS

brew install ggerganov/ggerganov/waver

More Repositories

1

llama.cpp

LLM inference in C/C++
C++
55,349
star
2

whisper.cpp

Port of OpenAI's Whisper model in C/C++
C
25,242
star
3

ggml

Tensor library for machine learning
C
9,288
star
4

kbd-audio

🎀⌨️ Acoustic keyboard eavesdropping
C++
7,569
star
5

imtui

ImTui: Immediate Mode Text-based User Interface C++ Library
C++
2,421
star
6

wave-share

Serverless, peer-to-peer, local file sharing through sound
C++
1,955
star
7

imgui-ws

Dear ImGui over WebSockets
C++
373
star
8

dot-to-ascii

Graphviz to ASCII converter using Graph::Easy
HTML
371
star
9

hnterm

πŸ“ƒ Hacker News in the terminal
C++
144
star
10

ggmorse

Morse code decoding library
C++
136
star
11

whisper.spm

whisper.cpp package for the Swift Package Manager
C
120
star
12

tweet2doom

Tweet to play Doom
Shell
83
star
13

wave-gui

Yet another data-over-sound tool
C++
70
star
14

wtf-tui

Text-based UI tool for configuring the WTF terminal dashboard
C++
66
star
15

incppect

Inspect C++ memory in the browser
C++
63
star
16

ggweb

Template for C++ GUI apps that can run in the browser
C
54
star
17

ggterm

Terminal configuration for C++ development with Vim
Vim Script
34
star
18

diff-challenge

Is this even possible?
Shell
27
star
19

wordle-bg

πŸ‡§πŸ‡¬ Wordle clone in Bulgarian
C++
27
star
20

hnreplies

Scrape Hacker News replies
C++
22
star
21

intervals

Downsampling array of intervals
C++
21
star
22

wave-em

Data over sound in the browser
C++
20
star
23

typing-battles

A multiplayer typing game (server: C++/WebSockets, client: JS)
C++
18
star
24

morse-meme

Meme generator in Bash
Shell
16
star
25

tweet2doom-data

@tweet2doom data and tools
JavaScript
16
star
26

ggwave-java

Minimal Java app for Android using ggwave
Java
14
star
27

ggwave-arduino

Mirror of ggwave used in the Arduino Library Manager
C++
14
star
28

imgui-em

Emscripten port of Dear ImGui (not maintained)
C++
14
star
29

ggwave-objc

Minimal Objective-C app for iOS using ggwave
Objective-C
10
star
30

ggwords

Generate language n-gram statistics
C++
10
star
31

ggerganov.github.io

JavaScript
10
star
32

imtui-template

Template repo for simple ImTui apps
C++
9
star
33

ggwave-spm

ggwave package for the Swift Package Manager
C++
8
star
34

asteroid-generator

The demo generates and renders asteroids floating in space. The shape and the texture of the generated asteroids are procedurally generated. The space background is procedurally generated as well.
C++
7
star
35

ggint

Poor man's big integer arithmetic operations
C++
6
star
36

ggsock

Non-blocking sockets wrapper
C++
5
star
37

hnguessr

Guess the Hacker News titles
C++
5
star
38

ggimg

Poor man's 2d and 3d image operations
C++
4
star
39

load-em

Load a local file in C++ Emscripten program
HTML
4
star
40

the-story

Collaborative storytelling experiment
HTML
4
star
41

tweet2btc

BTC price predictions via Twitter Polls
Shell
3
star
42

site-wave-share

A dedicated page for the wave-share tool:
JavaScript
3
star
43

ocl-lights

Pixel perfect 2D shadows on the GPU
C++
3
star
44

font-rasterizer

Simple TTF rasterizer
C
3
star
45

toto-check

See how many times you could have won the lottery
HTML
3
star
46

puzzle-solver

C++
2
star
47

OSSRH-94491

Jira
1
star
48

homebrew-ggerganov

My Homebrew tap for projects that are not notable enough
Ruby
1
star