ggwave: передача данных звуком от Георгия Герганова

ggwave: данные звуком

ggwave это маленькая библиотека Георгия Герганова, того самого автора llama.cpp и whisper.cpp, для передачи данных звуком. Динамик одного устройства пищит, микрофон другого слушает и достаёт байты. Никакой сети, Bluetooth или пары не нужно, поэтому автор так и пишет: связь между air-gapped устройствами, то есть физически отключёнными от сети. Лицензия MIT, на GitHub почти 7900 звёзд.

Что это и зачем

Объёмы маленькие: от 8 до 16 байт в секунду в зависимости от параметров протокола, для сообщения переменной длины максимум 140 байт. Файл так не перешлёшь, а вот ссылку, ключ, токен пары, команду устройству вполне. Для надёжности данные защищены кодами Рида Соломона.

Важная деталь: ggwave сам со звуковой картой не работает. Он только генерирует и разбирает «сырую» волну, а играть и записывать её вы можете чем угодно, хоть PulseAudio, хоть ALSA, хоть Web Audio, достаточно отдать библиотеке колбэки для очереди сэмплов. Поддерживаются частоты дискретизации от 6 до 96 кГц.

Примеры применения из README: рассылка одному многим без сервера (проект wave-share для обмена файлами со звуковой сигнализацией), интернет вещей на микроконтроллерах, «звуковые QR-коды», например раздать буфер обмена соседним устройствам, обмен контактами и публичными ключами (PairSonic), авторизация.

Как это работает

Модуляция многочастотная FSK, частотная манипуляция. Данные режутся на куски по 4 бита. В каждый момент передаются 3 байта шестью тонами, по тону на каждый 4-битный кусок. Тоны берутся из диапазона 4,5 кГц, разбитого на 96 частот с шагом 46,875 Гц: первые 16 частот кодируют первый кусок, следующие 16 второй и так далее. Для слышимых протоколов отсчёт идёт от 1875 Гц, для ультразвуковых от 15 000 Гц.

Приёмник ловит специальные звуковые маркеры начала и конца передачи, записывает звук между ними, делает преобразование Фурье, смотрит, какие частоты звучали, и собирает биты обратно. В конце декодер Рида Соломона исправляет ошибки. Есть и режим фиксированной длины, тогда маркеры не нужны.

Протоколы и ультразвук

В ggwave.h описаны четыре семейства протоколов, каждое в вариантах Normal, Fast и Fastest. Разница между ними в том, сколько кадров уходит на один кусок данных: 9, 6 или 3, то есть быстрее значит менее устойчиво к шуму.

  • Обычные слышимые: Normal, Fast, Fastest.
  • Ультразвуковые [U]: тот же принцип, но с 15 кГц. На слух такую передачу почти не заметно.
  • [DT]: низкочастотные, по одному байту за раз, для слабого железа.
  • [MT]: низкочастотные однотоновые, тоже для микроконтроллеров.

Плюс десять слотов CUSTOM_0…CUSTOM_9 под свои параметры. DT и MT появились в 0.4.0, вместе с большим рефакторингом под микроконтроллеры: ноль выделений памяти во время работы, без заголовков STL, лучше FFT и меньше расход памяти. В той же версии добавили Direct Sequence Spread.

Платформы, биндинги и демо

Ядро написано на C++ с C-интерфейсом. Собирается под Linux, macOS и Windows (MSYS2), через Emscripten в WebAssembly. Есть пакеты для Python (pip install ggwave) и Node.js (npm install ggwave), Swift Package для iOS и минимальные приложения на Objective-C и Java для Android, а сторонние авторы сделали версию на Kotlin Multiplatform.

В examples много интересного: ggwave-cli для передачи из терминала, ggwave-to-file и ggwave-from-file для WAV, спектрограмма, приём на ESP32, Raspberry Pi Pico и Arduino RP2040, передача с Arduino Uno, r2t2 для передачи через PC-спикер, e-paper бейдж ggtag, который программируется звуком, и даже ggwave-fm для передачи по радио через HackRF.

Самое простое демо это waver, графическое приложение для приёма и передачи. Оно есть в App Store, Google Play и Snap Store, на macOS ставится через brew, а в браузере открывается на waver.ggerganov.com. Ещё два браузерных демо: ggwave.ggerganov.com и ggwave-js.ggerganov.com.

Релизы и активность

Проект не новый: первые версии вышли в 2021 году, крупная 0.4.0 в июле 2022. Потом была пауза, и 21 марта 2026 вышел ggwave v0.4.3, он же на PyPI. В апреле 2026 были ещё правки упаковки Debian и Emscripten. В README появилась ссылка на научную статью ACM об оценке схем акустической передачи данных между соседними умными устройствами. Развивается проект неспешно, но он и не про гонку функций: библиотека маленькая и делает одно дело.

Как попробовать

Быстрее всего без сборки: сгенерировать WAV через HTTP-сервис автора и проиграть рядом с телефоном, где открыт waver.

# слышимый вариант
curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello%20world!' --output hello.wav

# ультразвук (протокол 4)
curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello%20world!&p=4' --output hello.wav

Из Python, пример из репозитория. Нужен ещё PyAudio для работы со звуком:

pip install ggwave pyaudio
import ggwave, pyaudio

p = pyaudio.PyAudio()
waveform = ggwave.encode("hello python", protocolId=1, volume=20)
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=48000,
                output=True, frames_per_buffer=4096)
stream.write(waveform, len(waveform) // 4)
stream.stop_stream(); stream.close(); p.terminate()

Приём устроен так же: читаете поток с микрофона кусками по 1024 сэмпла и отдаёте в ggwave.decode, он вернёт байты, когда поймает сообщение. Пример receive.py лежит в examples/ggwave-py.

Сборка из исходников с примерами на SDL2, включая ggwave-cli и waver:

sudo apt install libsdl2-dev
git clone https://github.com/ggerganov/ggwave --recursive
cd ggwave && mkdir build && cd build
cmake ..
make
./bin/ggwave-cli

Есть и цель make deb для локальных пакетов libggwave-dev и python3-ggwave. На Linux waver ставится из snap, не забудьте дать ему доступ к микрофону:

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

Источники и ссылки


Комментарии загружаются…