通信物联网嵌入式【免费下载链接】ggwaveTiny>项目地址https://gitcode.com/GitHub_Trending/gg/ggwave点击查看免费下载导读examples/ggwave-cli/README.md 介绍的ggwave-cli是 ggwaveTiny># Ubuntu / Debian sudo apt install libsdl2-dev # macOSHomebrew brew install sdl2 # MSYS2Windows pacman -S git cmake make mingw-w64-x86_64-dlfcn mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2依赖项列表与命令均来自 README.md 的 Building 章节。若系统已安装 SDL2 但 CMake 找不到可在配置时加-D USE_FINDSDL2ON使用仓库自带的 cmake/sdl2/FindSDL2.cmake见 examples/CMakeLists.txt。2.2 构建git clone https://gitcode.com/GitHub_Trending/gg/ggwave --recursive cd ggwave mkdir build cd build cmake .. make # 运行 ./bin/ggwave-cli要点顶层 CMakeLists.txt 中GGWAVE_BUILD_EXAMPLES在独立构建时默认开启示例因此被编译examples/CMakeLists.txt 中ggwave-cli仅在非 Emscripten 且启用 SDL2时加入构建add_subdirectory(ggwave-cli)位于if (EMSCRIPTEN) ... else() ... endif()分支之外但受GGWAVE_SUPPORT_SDL2门控examples/ggwave-cli/CMakeLists.txt 显示可执行文件链接了ggwave、ggwave-common、ggwave-common-sdl2三个库并需要Threads${CMAKE_THREAD_LIBS_INIT}因为 main 函数里用到了std::thread。2.3 基本用法启动后终端进入交互式输入循环$ ./bin/ggwave-cli程序首先枚举并打印当前机器上可用的音频设备接着列出可用的 Tx发送协议然后提示Enter text:。此时输入一行文字并回车→ 立即通过扬声器发送直接按回车空输入→ 使用上一次的文本重新发送Re-sending ...对方设备运行同一工具或任意 ggwave 接收端收到数据后会在自己的终端打印。注意程序启动时会先printf打印用法说明再进入循环所以标准输出里会先出现参数帮助信息见 main.cpp这是正常现象不是报错。三、命令行参数详解程序启动时打印的用法为main.cppUsage: ./ggwave-cli [-cN] [-pN] [-tN] [-lN] -cN - select capture device N -pN - select playback device N -tN - transmission protocol -lN - fixed payload length of size N, N in [1, 64] -d - use Direct Sequence Spread (DSS) -v - print generated tones on resend各参数解析来自 ggwave-common.cpp 的 parseCmdArguments以-开头、长度大于 1 的参数其第二个字符作为 key剩余部分argv[i] 2作为 value。因此-c2表示选择 2 号采集设备-d无值即布尔开关。逐项说明参数含义默认值说明-cN选择第 N 个采集麦克风设备0第一个设备设备编号即启动时打印列表中的序号来自SDL_GetAudioDeviceName(i, SDL_TRUE)见 ggwave-common-sdl2.cpp-pN选择第 N 个播放扬声器设备0第一个设备编号来自SDL_GetAudioDeviceName(i, SDL_FALSE)ggwave-common-sdl2.cpp-tN选择发送协议编号 N1编号对应启动时打印的 Available Tx protocols 列表序号-lN固定载荷长度 N字节变长模式N ∈ [1, 64]上限即GGWave::kMaxLengthFixed-d启用 DSS直序扩频关闭对应GGWAVE_OPERATING_MODE_USE_DSS-v重发时打印生成的音调频率Hz关闭调试用见下文音调打印小节对应源码解析main.cppconst auto argm parseCmdArguments(argc, argv); const int captureId argm.count(c) 0 ? 0 : std::stoi(argm.at(c)); const int playbackId argm.count(p) 0 ? 0 : std::stoi(argm.at(p)); const int txProtocolId argm.count(t) 0 ? 1 : std::stoi(argm.at(t)); const int payloadLength argm.count(l) 0 ? -1 : std::stoi(argm.at(l)); const bool useDSS argm.count(d) 0; const bool printTones argm.count(v) 0;典型用法示例# 用默认设备、默认协议发送 ./bin/ggwave-cli # 指定麦克风 1、扬声器 0用协议 5 发送 ./bin/ggwave-cli -c1 -p0 -t5 # 固定 16 字节载荷 启用 DSS近距离抗噪场景 ./bin/ggwave-cli -l16 -d # 调试重发时打印每个音调的频率 ./bin/ggwave-cli -v3.1 关于-tN协议编号与音调频率启动时打印的协议列表来自 ggwave.h 的Protocols::kDefault()非 Arduino 精简配置下共 12 个协议编号即数组下标发送时按编号取用main.cpp编号协议名特征0Normal可听频段freqStart401Fast可听频段、更快2Fastest可听频段、最快3[U] Normal超声频段freqStart3204[U] Fast超声频段5[U] Fastest超声频段6[DT] Normal双音调dual-tonefreqStart247[DT] Fast双音调8[DT] Fastest双音调9[MT] Normal多音调multi-toneextra2freqStart2410[MT] Fast多音调11[MT] Fastest多音调可听 vs 超声超声协议[U]人耳几乎听不到适合需要静默传输的场合可听协议便于肉眼确认扬声器在发声。音调频率换算每个音调元素是 FFT bin 索引实际频率freq_hz (protocol.freqStart tone) * hzPerSample单个音调时长duration_ms framesPerTx * (1000 * samplesPerFrame / sampleRate)ggwave.h。接收端默认启用所有 Rx 协议ggwave.h 的 toggle 说明因此发送端无需与接收端约定协议也能被解码但双方约定同一协议可减少误判、提高准确率官方建议见 ggwave_decode 注释。3.2-v音调打印的实现空输入触发重发时若开启-v程序遍历ggWave-txTones()对每个 tone 打印换算后的赫兹值-1表示一次 Tx 结束main.cppconst auto tones ggWave-txTones(); for (int i 0; i (int) tones.size(); i) { if (tones[i] 0) { printf( - end tx\n); continue; } const auto freq_hz (protocol.freqStart tones[i])*ggWave-hzPerSample(); printf( - tone %3d: %f\n, i, freq_hz); }注意txTones()返回的是上一次 encode() 的结果ggwave.h因此该输出只在重发内容不变时才有意义。3.3-lN固定长度与-dDSS 的底层含义payloadLength 0默认变长传输模式收发两端靠特殊 sound markers 标识起止ggwave.h 参数注释。payloadLength 0固定长度传输模式不发送 markers使用另一套解码流程对应内部decode_fixed()与decode_variable()两个私有方法ggwave.h适合载荷长度事先已知的场景上限GGWave::kMaxLengthFixed 64ggwave.h。DSS直序扩频叠加GGWAVE_OPERATING_MODE_USE_DSS位ggwave.h以牺牲带宽换取更强的抗噪/抗干扰能力近距离嘈杂环境下更稳。四、源码级执行流程剖析4.1 初始化GGWave_initGGWave_init(playbackId, captureId, payloadLength, 0.0f, useDSS)ggwave-common-sdl2.cpp内部完成SDL_Init(SDL_INIT_AUDIO)初始化音频子系统并设置SDL_HINT_AUDIO_RESAMPLING_MODEmedium枚举打印所有播放/采集设备名称以GGWave::kDefaultSampleRate48000 Hz请求打开播放设备16-bit signed、单声道、每帧 16×1024 样本与采集设备F32、单声道、每帧 1024 样本按 SDL 实际返回的格式把样本格式映射为GGWAVE_SAMPLE_FORMAT_*构造GGWave实例内部采样率固定为 48 kHz采集/播放采样率分别取自 SDL 实际获得的 specsamplesPerFrame kDefaultSamplesPerFrame 1024若useDSS为真则在 operating mode 上追加GGWAVE_OPERATING_MODE_USE_DSS位。payloadLength会作为ggwave_Parameters.payloadLength传入实例ggwave.h从而决定固定/变长两种收发模式。初始化失败时 main 返回 -1main.cpp。4.2 发送线程输入 → init → encodemain 启动一个std::threadmain.cppgetline(std::cin, input)读取一行空行则复用inputOld触发重发加锁后调用ggWave-init(input.size(), input.data(), GGWave::TxProtocolId(txProtocolId), 10)以10 为音量volume参数ggwave.h设置待发送数据实际波形生成不在线程内完成而是由主循环中GGWave_mainLoop()在txHasData() true时调用ggWave-encode()随后SDL_QueueAudio排队播放ggwave-common-sdl2.cpp。之所以用std::mutex包住init与GGWave_mainLoop是为了避免输入线程与主循环并发访问 GGWave 实例。这也是 examples/ggwave-cli/CMakeLists.txt 必须链接 Threads 的原因。4.3 接收主循环采集 → decode主循环每 1ms 执行一次main.cppwhile (true) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); { std::lock_guardstd::mutex lock(mutex); GGWave_mainLoop(); } }GGWave_mainLoop()ggwave-common-sdl2.cpp的逻辑若发送队列为空暂停播放从采集设备队列取samplesPerFrame * sampleSizeInp字节即一帧 1024 样本调用ggWave-decode()如果解码返回 false 打印告警若队列积压超过 32 帧则清空队列处理慢速解码的背压保护若发送队列非空暂停采集编码并排队输出。decode()内部先做 FFT将检测到的音调还原为二进制位再经 Reed-Solomon 解码得到原始数据参见 README.md 的 Demodulation 小节。若解码出数据会在后续循环中打印接收结果读取自ggWave-rxData()ggwave.h。4.4 退出清理inputThread.join()之后依次调用GGWave_deinit()、SDL_CloseAudio()、SDL_Quit()main.cpp。GGWave_deinit()ggwave-common-sdl2.cpp会重置实例并关闭采集/播放设备。由于输入线程是死循环实际退出通常靠 CtrlC 中断进程。五、实战场景与建议5.1 两台设备互发在两台都装有扬声器和麦克风的机器上分别运行./bin/ggwave-cli设备靠近一般几米内、麦克风不被遮挡一端输入文本回车即可在另一端看到打印。可用超声协议如-t3降低噪音干扰或-d增强抗噪。5.2 与仓库其他工具联动ggwave-cli使用默认 48 kHz、S16/F32 单声道 SDL 设备兼容性最好的对端包括ggwave-rx纯接收演示可作打印端waver图形界面收发工具便于可视化确认频谱ggwave-to-file ggwave-from-file先离线生成 WAV 再解码适合无音频硬件的调试环境。5.3 调试技巧用-v观察发送的音调频率对照 README.md 的调制表dF 46.875 Hz可听协议F0 1875 Hz验证信号内容发现收到了但内容乱码时先确认双方协议频段一致可听 vs 超声再考虑开启-d同一台机器开两个终端互发也可行但需注意回声与设备独占冲突建议优先用两台设备误码率偏高时可固定载荷长度-lN减少 marker 开销前提是收发双方都知道 N。六、相关文件索引文件作用examples/ggwave-cli/main.cppggwave-cli 全部实现参数解析、输入线程、主循环examples/ggwave-cli/CMakeLists.txt编译目标与依赖ggwave / ggwave-common / ggwave-common-sdl2 / Threadsexamples/ggwave-common.cppparseCmdArguments命令行解析实现examples/ggwave-common-sdl2.cppSDL2 音频设备封装GGWave_init/GGWave_mainLoop/GGWave_deinitexamples/ggwave-common-sdl2.hSDL2 辅助接口声明include/ggwave/ggwave.hGGWave C/C APIinit/encode/decode/ 协议定义 / 常量kMaxLengthFixed、kDefaultSampleRate等src/ggwave.cppGGWave 核心实现FSK 调制解调、Reed-Solomon、FFTREADME.md项目总览、技术细节调制表、构建指南七、小结ggwave-cli是 ggwave 生态中门槛最低的开箱即用命令行收发工具一条./bin/ggwave-cli命令即可完成输入文本 → 声波发送 → 麦克风接收 → 打印还原的完整闭环。本文从参数、构建到源码调用链逐层拆解了它的实现参数由 parseCmdArguments 解析并映射到 GGWave API音频 I/O 由 ggwave-common-sdl2.cpp 封装协议与音调频率的换算依据全部可在 ggwave.h 中验证。掌握它之后无论是做数据透传实验、验证音频链路还是以此为模板扩展自己的收发程序都能快速上手。赞分享通信物联网嵌入式【免费下载链接】ggwaveTiny>项目地址https://gitcode.com/GitHub_Trending/gg/ggwave点击查看免费下载相关推荐使用 ggwave 的 r2t2 通过主板 PC 扬声器传输数据命令行实战指南使用 ggwave 的 r2t2 通过主板 PC 扬声器传输数据命令行实战指南 r2t2 是 ggwave 开源库Tiny data over sound通信物联网嵌入式TinyUSB音频设备开发UAC2麦克风与扬声器实现TinyUSB音频设备开发UAC2麦克风与扬声器实现 引言 你是否还在为嵌入式系统中的USB音频设备开发而烦恼是否想要快速实现一个符合UAC2USB Au嵌入式驱动开发通信物联网3行代码实现麦克风声波捕获ggwaveSDL2实时音频处理实战指南3行代码实现麦克风声波捕获ggwaveSDL2实时音频处理实战指南 你还在为设备间无线数据传输烦恼当蓝牙配对失败、Wi Fi信号不稳定时声波传输或许是最通信物联网嵌入式上一篇QMK 固件实战alt34 34 键分体键盘的构建与 EE_HANDS 刷写指南下一篇LLM Zoomcamp RAG 提示词构建指南从检索结果到可落地的 Instructions 与 User Prompt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?