用声音传数据:ggwave 声波数据传输完整指南
【免费下载链接】ggwaveTiny>项目地址: https://gitcode.com/GitHub_Trending/gg/ggwave
把 WiFi 凭据发给一台断网的 ESP32?让对面设备的喇叭叫几声就行。ggwave 是一个轻量的声波数据传输库:把字节编码成一串声波音调,接收端再把声音解回数据,让没有线缆、没有网络的设备互传小数据,常用于物联网配网、设备间近距离配对、文件分享这类场景。
线缆会成为麻烦的时候
这些情况你可能都遇到过:新买的 ESP32 躺在机房里,断网、手边没有串口线,WiFi 凭据只能回工位拖线去配;两台隔离的电脑想递一小段密钥,USB 线却在抽屉里;桌上块带喇叭的单片机,你想从手机给它递文字,可它没有蓝牙模块。这些需求都不值当加一个无线模块,却全卡在"没有通道"上——而声音,是任何带喇叭和麦克风的设备本来就有的通道。ggwave 做的事,就是让这条通道能跑数据。
声波怎么驮字节:原理速览
这一节回答"声音为什么能当数据线用"。ggwave 采用多频 FSK 调制:数据先切成 4-bit 小块,每个小块对应一个固定频点,一次用 6 个音调同时发出 3 字节,共 96 个等间距频点铺在 4.5 kHz 带宽内——可听声系列从 1875 Hz 起,超声波系列在 15 kHz。数据前后包着声音标记,接收端听到标记才开始录,再用 FFT 还原频谱、把频点读回比特,最后经 Reed-Solomon 纠错码把原始数据抠出来。库本身只管"字节 ↔ 波形"的换算,音频的进出由你自己接。
waver 客户端界面:一边输入文本,另一边解码出收到的内容
选协议时记住三档就够了:
GGWAVE_PROTOCOL_AUDIBLE_NORMAL / FAST / FASTEST:人耳可闻,方便调试;FAST 系列更快但对噪声更敏感GGWAVE_PROTOCOL_ULTRASOUND_NORMAL / FAST / FASTEST:15 kHz 超声波,听不见、更私密,传输距离更短GGWAVE_PROTOCOL_MT_*与DT_*:低频单音系列,便宜蜂鸣器也能发,MT 是一对多广播
五步跑通声波数据传输 Demo
这是你真正要动手的部分,跑完手里会有一个能用的收发对。核心 API 只有三个:ggwave_init、ggwave_encode、ggwave_decode。
1. 克隆并构建。库本身无第三方依赖,但示例需要 SDL2(Ubuntu:sudo apt install libsdl2-dev)。
git clone https://gitcode.com/GitHub_Trending/gg/ggwave --recursive cd ggwave && mkdir build && cd build cmake .. && make为什么这样构建:一条命令把库和全部示例都编出来,bin/下有一堆能直接跑的程序。
2. 跑一把./bin/ggwave-cli。敲一句文本就是可工作的发送端;没配音响也没关系,ggwave-to-file能把波形写成 WAV,先用眼睛验证流程。
3. 初始化实例。就两行:ggwave_getDefaultParameters()拿默认参数,塞给ggwave_init(),返回实例 id。默认 48 kHz、每帧 1024 采样、采样格式都配好了,不用改就能起步。
4. 把数据编码成波形。正确姿势是"先问再写":
ggwave_Parameters p = ggwave_getDefaultParameters(); ggwave_Instance inst = ggwave_init(p); const char * msg = "hello ggwave"; int n = ggwave_encode(inst, msg, 12, GGWAVE_PROTOCOL_AUDIBLE_FAST, 25, NULL, 1); char waveform[8192]; ggwave_encode(inst, msg, 12, GGWAVE_PROTOCOL_AUDIBLE_FAST, 25, waveform, 0);为什么先来一次 query:query=1时不真正编码,只告诉你会生成多大的波形;先照这个尺寸备好缓冲区再实写,不会溢出。音量在 0–100,25 是安全值。
5. 解码:把麦克风数据一帧一帧喂进去。
char payload[256]; while (true) { // 读一帧麦克风采样到 micFrame int k = ggwave_decode(inst, micFrame, frameBytes, payload); if (k > 0) printf("收到 %d 字节\n", k); }注意:解码结果不带\0结尾,想当字符串打印就自己补上。
跑通之后的效果大致是这样:
一次完整的 ggwave 声波数据传输:发送端发声,接收端解码出文本
跨平台实战:Arduino、浏览器、桌面怎么接
这一节回答"我的硬件上怎么接",每个平台给你 50 字内的要点。
- Arduino Uno(只发):一个通用蜂鸣器就够。示例用
GGWAVE_OPERATING_MODE_TX_ONLY_TONES模式只输出音调列表,再逐条tone()播放,AVR 这种小内存芯片也跑得动。完整例程见 examples/arduino-tx。 - ESP32(只收):模拟麦(如 MAX9814)接 GPIO35,或用 I2S MEMS 麦 SPH0645,例程还带 OLED 显示,见 examples/esp32-rx。
- 桌面与浏览器:桌面跑
ggwave-cli或 waver 图形应用(examples/waver);浏览器走 bindings/javascript/ 里的 Web 封装;Python 一行pip install ggwave即可用。
Arduino Uno 电路:按钮触发发送,蜂鸣器发出 ggwave 音调
调优与踩坑:收不到数据时怎么办
这几条都是跑起来之后会真实撞上的:
- 如果一直收不到,先调音量:发送端音量放到 15–30,收发距离收到几十厘米内再试。
- 如果环境吵,换超声波系列协议,或打开 DSS(直接序列扩展)模式抗干扰。
- 如果喇叭发不出 MT/DT 协议所需的 1–2 kHz 低频,把收发两端的
freqStart同时上调相同的 bin 数,一个 bin 等于 46.875 Hz。 - 如果想一次发更长的数据:变长负载单次上限 140 字节,固定长度负载上限 64 字节,更大的数据要靠你自己的协议分片。
- 如果误报多,用
ggwave_rxToggleProtocol只留你需要的协议,既能减少误检也能省内存。 - 如果你在意距离:安静环境下可听声协议通常能到几米,超声波只有 1–2 米,别指望超声波跨房间。
延伸与资源
想继续挖,直接看仓库里这些路径:
- examples/ggwave-cli:命令行收发工具,验证最快
- examples/ggwave-to-file:把文本编码成 WAV 文件,没有喇叭也能调试
- examples/ggwave-from-file:反过来,解码 WAV 文件离线回放
- examples/ggwave-py/send.py:Python 发送完整例程
- examples/spectrogram:频谱图可视化工具,亲眼看频点落在哪
- tests/test-ggwave.cpp:带加噪测试的 API 用法参考
下一步动作:开两个终端,把 examples/ggwave-py/send.py 和 examples/ggwave-py/receive.py 跑起来,两分钟后你手里就有第一次完整的 ggwave 声波数据传输。
【免费下载链接】ggwaveTiny>项目地址: https://gitcode.com/GitHub_Trending/gg/ggwave
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考