Code Monkey home page Code Monkey logo

ggwave's Introduction

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

# 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
ggtag Sound-programmable e-paper badge PDM mic
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

ggwave's People

Contributors

epxzzy avatar ggerganov avatar guilt avatar midijohnny avatar rgerganov avatar tayler6000 avatar vpalmisano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ggwave's Issues

Does not work/build on Ubuntu 22.04

It installs as a snap, and trying to run it, I get:

Testing for explicit PulseAudio choice...
...and PulseAudio has been explicitly chosen, so using it.
libGL error: MESA-LOADER: failed to open i965 (search paths /usr/lib/x86_64-linux-gnu/dri:$${ORIGIN}/dri:/usr/lib/dri)
libGL error: failed to load driver: i965
libGL error: MESA-LOADER: failed to open i965 (search paths /usr/lib/x86_64-linux-gnu/dri:$${ORIGIN}/dri:/usr/lib/dri)
libGL error: failed to load driver: i965
libGL error: MESA-LOADER: failed to open swrast (search paths /usr/lib/x86_64-linux-gnu/dri:$${ORIGIN}/dri:/usr/lib/dri)
libGL error: failed to load driver: swrast
X Error: GLXBadContext
Request Major code 152 (GLX)
Request Minor code 6 ()
Error Serial #111
Current Serial #110

Building is not possible, either:

cmake ..
CMake Error: File /home/archon/Documents/var/ggwave/bindings/ios/Makefile-tmpl does not exist.
CMake Error at CMakeLists.txt:19 (configure_file):
configure_file Problem configuring file

-- SDL2_INCLUDE_DIRS = /usr/include/SDL2
-- SDL2_LIBRARIES = -L/usr/lib/x86_64-linux-gnu -lSDL2
CMake Error at examples/third-party/CMakeLists.txt:5 (add_subdirectory):
The source directory

/home/archon/Documents/var/ggwave/examples/third-party/ggsock

does not contain a CMakeLists.txt file.

-- Configuring incomplete, errors occurred!
See also "/home/archon/Documents/var/ggwave/build/CMakeFiles/CMakeOutput.log".

C library ggwave_decode: logging of binary data

The ggwave library does logging via printf by default. And will print out the data it has received as if it is text. When sending binary data this can lead to corrupted terminals as some binary data can be interpreted as control characters.

Suggested fix:
-allow disabling of logging altogether
-ideally: don't log via printf, instead allow calling applications to configure logging via their own callbacks.
-make no assumptions about the data, blindly printing the data (except perhaps under a debug log level) can lead to unintended behavior.

Arduino example arduino-tx cant compile: undefined reference to `GGWave::Protocols::kDefault()::data'

Dear Georgi,

I can´t get the arduino-tx example to compile. All necessary files seem to be in place, but its complaining about not having a reference to GGWave::Protocols::kDefault()::data.
Compile log error:

C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0x0): undefined reference to `GGWave::Protocols::kDefault()::data'
C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0xc): undefined reference to `GGWave::Protocols::kDefault()::data'
C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0x18): undefined reference to `GGWave::Protocols::kDefault()::data'
C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0x24): undefined reference to `GGWave::Protocols::kDefault()::data'
C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0x30): undefined reference to `GGWave::Protocols::kDefault()::data'
C:\Users\fl0wtec\AppData\Local\Temp\arduino_build_838640\sketch\src\ggwave.cpp.o:(.rodata+0x3c): undefined reference to `GGWave::Protocols::kDefault()::data'
collect2.exe: error: ld returned 1 exit status

Is this reference indeed missing or am I doing anything wrong?
This is the file/folder structure I´m working with:
image

Thanks & Best regards
fl0wtec

Possible to perform simultaneous communications

Hi, I was wondering if someone could point me in the right direction. I've been experimenting with ggwave-js and am trying to create a chat-type project that allows back and forth between a group of people, however, issues naturally occur when two devices are transmitting at the same time, is there any way to get around this?

Cannot build pass for ggwave on Windows

I already install msys2 mingw64 and follow below steps to install related libraries.

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

I use visual studio 2022 and open ggwave folder, but it cannot find SDL2. Then it will show error message with "Aborting".
How to resolve it?
BTW, which IDE do you use for development? Or you just use command line to build ggwave binaries?

Python 3.11 pip install ggwave fails.

Hello. I am trying to run my gui ggwaver in a new python, but pip install ggwave throws me an error. I tried to pip install it from setup.py, but no success.


pip install ggwave                                                                                       
Collecting ggwave                                                                                                       
  Using cached ggwave-0.4.2.tar.gz (76 kB)                                                                              
  Preparing metadata (setup.py) ... -                                                                                   
done
Installing collected packages: ggwave                                                                                   
  DEPRECATION: ggwave is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproje
ct.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement i
s to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559               
  Running setup.py install for ggwave ... -                                                                             
error
  error: subprocess-exited-with-error                                                                                   
  × Running setup.py install for ggwave did not run successfully.                                                       
  │ exit code: 1                                                                                                        
  ╰─> [22 lines of output]                                                                                              
      running install                                                                                                   
      C:\Users\dsinc\Python311\Lib\site-packages\setuptools\command\install.py:34: SetuptoolsDeprecationWarning: setup.p
y install is deprecated. Use build and pip and other standards-based tools.                                             
        warnings.warn(                                                                                                  
      running build                                                                                                     
      running build_ext                                                                                                 
      building 'ggwave' extension                                                                                       
      creating build                                                                                                    
      creating build\temp.win-amd64-cpython-311                                                                         
      creating build\temp.win-amd64-cpython-311\Release                                                                 
      creating build\temp.win-amd64-cpython-311\Release\ggwave                                                          
      creating build\temp.win-amd64-cpython-311\Release\ggwave\src                                                      
      "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.33.31629\bin\HostX86\x64\cl.exe" 
/c /nologo /O2 /W3 /GL /DNDEBUG /MD -Iggwave/include -Iggwave/include/ggwave -IC:\Users\dsinc\Python311\include -IC:\Use
rs\dsinc\Python311\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.33.31629\i
nclude" "-IC:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\VS\include" "-IC:\Program Files (
x86)\Windows Kits\10\include\10.0.18362.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.18362.0\\um" "-I
C:\Program Files (x86)\Windows Kits\10\\include\10.0.18362.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include
\10.0.18362.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.18362.0\\cppwinrt" /EHsc /Tpggwave.bycytho
n.cpp /Fobuild\temp.win-amd64-cpython-311\Release\ggwave.bycython.obj -O3 -std=c++11                                    
      cl : Command line warning D9002 : ignoring unknown option '-O3'                                                   
      cl : Command line warning D9002 : ignoring unknown option '-std=c++11'                                            
      ggwave.bycython.cpp                                                                                               
      ggwave/include/ggwave\ggwave.h(454): warning C4244: 'return': conversion from 'float' to 'int', possible loss of d
ata                                                                                                                     
      ggwave.bycython.cpp(2010): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
      ggwave.bycython.cpp(2052): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
      ggwave.bycython.cpp(2291): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
      ggwave.bycython.cpp(5722): error C2027: use of undefined type '_frame'                                            
      C:\Users\dsinc\Python311\include\pytypedefs.h(22): note: see declaration of '_frame'                              
      error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.33.31629\\
bin\\HostX86\\x64\\cl.exe' failed with exit code 2                                                                      
      [end of output]                                                                                                   
  note: This error originates from a subprocess, and is likely not a problem with pip.                                  
error: legacy-install-failure                                                                                           
× Encountered error while trying to install package.                                                                    
╰─> ggwave                                                                                                              
note: This is an issue with the package mentioned above, not pip.                                                       
hint: See above for output from the failure.                                                                            
C:\Users\dsinc>                                                                                                         

Difference between Waver protocols

I'm not entirely sure, what's the difference between normal, ultrasound, dual-tone and mono-tone Tx protocols aviable in Waver.
What are the practical benefits and limitations of each of them? Which one should I choose when?

Usage in AV applications for measuring AV desynchronization

Hi!

I'm currently looking into writing an application that encodes a timestamp into a sound signal for the purpose of measuring desynchronization between audio and video (I already transmit data in the video by writing a bit pattern in the video pixels by modifying the luminance).
For that purpose it's important that the library gives me the exact timestamp of the start of receiving the preamble, is that doable?

Web Demo issue

Very great library!

Firstly, for the Web Demo, inside onchange event of "Tx Protocol" combobox , please assign the integer value to protocolId instead of a string value. Otherwise, the "broadcast" cannot work properly when calling _sendData.

Secondly, on MacOS & iOS Safari, the Web Demo can _getText from hearable sound but not from Ultrasound. They both work on Mac Chrome though. Any idea please? Because I want to embed this into a iPhone Cordova app. Many thanks!

Sending files purely via sound

This project is exactly what I was looking for except the limitation for message length and the transfer of files. I suggest the possibility of sending files purely over sound, without any additional type of connection. This could be beneficial in environment without any internet connection and for secure transfer of private data (such as private keys) without any need of LAN network or any internet at all.

Not sure how difficult would be implement splicing data into 140 chars and then sending initial message with number of messages to be transmitted and then checksum in ending message. Or using less then 140 chars plus initial integer for the number of messages. Then receiver would request these messages to be sent again in case of transmission failure.

Hope this makes sense.

problem installing python package

fatal error C1083: Cannot open source file: 'ggwave.bycython.cpp': No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe' failed with exit status 2

i am recieving this error when installing ggwave in python using "pip install ggwave" . researched a lot but no solution found. maybe one possible solution is install using wheel file but wheel file is not present for ggwave.

same issue with pyaudio but i managed to install it using pipwin install pyaudio.
Another solution is to add ggwave in pipwin package list.

Full error ::::
Collecting ggwave
Using cached ggwave-0.2.2.tar.gz (62 kB)
Building wheels for collected packages: ggwave
Building wheel for ggwave (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: 'c:\users\meetr\appdata\local\programs\python\python38\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"'; file='"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\Meetr\AppData\Local\Temp\pip-wheel-v9m_y4jz'
cwd: C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a
Complete output (73 lines):
running bdist_wheel
running build
running build_ext
building 'ggwave' extension
creating build
creating build\temp.win-amd64-3.8
creating build\temp.win-amd64-3.8\Release
creating build\temp.win-amd64-3.8\Release\ggwave
creating build\temp.win-amd64-3.8\Release\ggwave\src
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iggwave/include -Iggwave/include/ggwave -Ic:\users\meetr\appdata\local\programs\python\python38\include -Ic:\users\meetr\appdata\local\programs\python\python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /EHsc /Tpggwave.bycython.cpp /Fobuild\temp.win-amd64-3.8\Release\ggwave.bycython.obj -O3 -std=c++11
cl : Command line warning D9002 : ignoring unknown option '-O3'
cl : Command line warning D9002 : ignoring unknown option '-std=c++11'
ggwave.bycython.cpp
ggwave.bycython.cpp(1881): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
ggwave.bycython.cpp(1923): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
ggwave.bycython.cpp(2162): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iggwave/include -Iggwave/include/ggwave -Ic:\users\meetr\appdata\local\programs\python\python38\include -Ic:\users\meetr\appdata\local\programs\python\python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /EHsc /Tpggwave/src/ggwave.cpp /Fobuild\temp.win-amd64-3.8\Release\ggwave/src/ggwave.obj -O3 -std=c++11
cl : Command line warning D9002 : ignoring unknown option '-O3'
cl : Command line warning D9002 : ignoring unknown option '-std=c++11'
ggwave.cpp
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(150): warning C4244: 'argument': conversion from 'uint16_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(150): warning C4244: 'argument': conversion from 'uint16_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(216): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(174): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(455): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(500): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(519): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
ggwave/src/ggwave.cpp(172): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(173): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(177): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(178): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(229): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data
ggwave/src/ggwave.cpp(230): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data
ggwave/src/ggwave.cpp(232): warning C4244: 'initializing': conversion from 'int' to 'float', possible loss of data
ggwave/src/ggwave.cpp(337): warning C4305: 'initializing': truncation from 'double' to 'float'
ggwave/src/ggwave.cpp(385): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(389): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(415): warning C4244: '=': conversion from 'double' to 'float', possible loss of data
ggwave/src/ggwave.cpp(499): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(524): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(528): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(639): warning C4244: '=': conversion from '_Ty' to '_Ty', possible loss of data
with
[
_Ty=float
]
and
[
_Ty=int16_t
]
ggwave/src/ggwave.cpp(649): warning C4244: '=': conversion from '_Ty' to 'uint8_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(656): warning C4244: '=': conversion from '_Ty' to 'uint8_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(663): warning C4244: '=': conversion from '_Ty' to 'uint16_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(1003): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1106): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1155): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1133): warning C4996: 'asctime': This function or variable may be unsafe. Consider using asctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
ggwave/src/ggwave.cpp(1182): warning C4996: 'asctime': This function or variable may be unsafe. Consider using asctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
ggwave/src/ggwave.cpp(1224): warning C4267: '+=': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1247): warning C4267: '-=': conversion from 'size_t' to 'int', possible loss of data
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe' failed with exit status 2

ERROR: Failed building wheel for ggwave
Running setup.py clean for ggwave
Failed to build ggwave
Installing collected packages: ggwave
Running setup.py install for ggwave ... error
ERROR: Command errored out with exit status 1:
command: 'c:\users\meetr\appdata\local\programs\python\python38\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"'; file='"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\Meetr\AppData\Local\Temp\pip-record-hja6gpmf\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\meetr\appdata\local\programs\python\python38\Include\ggwave'
cwd: C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a
Complete output (73 lines):
running install
running build
running build_ext
building 'ggwave' extension
creating build
creating build\temp.win-amd64-3.8
creating build\temp.win-amd64-3.8\Release
creating build\temp.win-amd64-3.8\Release\ggwave
creating build\temp.win-amd64-3.8\Release\ggwave\src
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iggwave/include -Iggwave/include/ggwave -Ic:\users\meetr\appdata\local\programs\python\python38\include -Ic:\users\meetr\appdata\local\programs\python\python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /EHsc /Tpggwave.bycython.cpp /Fobuild\temp.win-amd64-3.8\Release\ggwave.bycython.obj -O3 -std=c++11
cl : Command line warning D9002 : ignoring unknown option '-O3'
cl : Command line warning D9002 : ignoring unknown option '-std=c++11'
ggwave.bycython.cpp
ggwave.bycython.cpp(1881): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
ggwave.bycython.cpp(1923): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
ggwave.bycython.cpp(2162): warning C4244: 'argument': conversion from 'Py_ssize_t' to 'int', possible loss of data
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -Iggwave/include -Iggwave/include/ggwave -Ic:\users\meetr\appdata\local\programs\python\python38\include -Ic:\users\meetr\appdata\local\programs\python\python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /EHsc /Tpggwave/src/ggwave.cpp /Fobuild\temp.win-amd64-3.8\Release\ggwave/src/ggwave.obj -O3 -std=c++11
cl : Command line warning D9002 : ignoring unknown option '-O3'
cl : Command line warning D9002 : ignoring unknown option '-std=c++11'
ggwave.cpp
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(150): warning C4244: 'argument': conversion from 'uint16_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(150): warning C4244: 'argument': conversion from 'uint16_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon\gf.hpp(216): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(174): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(455): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(500): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\ggwave\src\reed-solomon/rs.hpp(519): warning C4267: 'argument': conversion from 'size_t' to 'uint8_t', possible loss of data
ggwave/src/ggwave.cpp(172): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(173): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(177): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(178): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(229): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data
ggwave/src/ggwave.cpp(230): warning C4244: 'initializing': conversion from 'float' to 'int', possible loss of data
ggwave/src/ggwave.cpp(232): warning C4244: 'initializing': conversion from 'int' to 'float', possible loss of data
ggwave/src/ggwave.cpp(337): warning C4305: 'initializing': truncation from 'double' to 'float'
ggwave/src/ggwave.cpp(385): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(389): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(415): warning C4244: '=': conversion from 'double' to 'float', possible loss of data
ggwave/src/ggwave.cpp(499): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(524): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(528): error C2065: 'M_PI': undeclared identifier
ggwave/src/ggwave.cpp(639): warning C4244: '=': conversion from '_Ty' to '_Ty', possible loss of data
with
[
_Ty=float
]
and
[
_Ty=int16_t
]
ggwave/src/ggwave.cpp(649): warning C4244: '=': conversion from '_Ty' to 'uint8_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(656): warning C4244: '=': conversion from '_Ty' to 'uint8_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(663): warning C4244: '=': conversion from '_Ty' to 'uint16_t', possible loss of data
with
[
_Ty=float
]
ggwave/src/ggwave.cpp(1003): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1106): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1155): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1133): warning C4996: 'asctime': This function or variable may be unsafe. Consider using asctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
ggwave/src/ggwave.cpp(1182): warning C4996: 'asctime': This function or variable may be unsafe. Consider using asctime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
ggwave/src/ggwave.cpp(1224): warning C4267: '+=': conversion from 'size_t' to 'int', possible loss of data
ggwave/src/ggwave.cpp(1247): warning C4267: '-=': conversion from 'size_t' to 'int', possible loss of data
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe' failed with exit status 2
----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\users\meetr\appdata\local\programs\python\python38\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"'; file='"'"'C:\Users\Meetr\AppData\Local\Temp\pip-install-azsi740u\ggwave_5580c82224ed49db82087eca3795e92a\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\Meetr\AppData\Local\Temp\pip-record-hja6gpmf\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\meetr\appdata\local\programs\python\python38\Include\ggwave' Check the logs for full command output.

Soundless file

Hi, I might be misunderstanding how to use the library but regarding the ggwave-to-file the readme states that by using the following commands in the terminal we would be able to produce audible and ultrasound files.

audible example

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

ultrasound example

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

When I run the ultrasound command with fast or fastest p codes. I still get a R2D2 like output sound in the audio. I was expecting that the file would contain just the inaudible frequencies that the phones would hear but we wouldn't.

I need to produce a file that I can merge into other sounds, so the inaudible property is really critical for me. Is it possible to generate audios without audible content to transmit the messages?

windows receive ultrasound difference

(1) Compile the source code under Windows to obtain waver.exe.

(2) On the same Windows computer, open waver.exe and then open the website address https://waver.ggerganov.com/.

(3) Another computer sends ultrasonic waves with a frequency of 15000-19500Hz.

(4) Waver.exe is difficult to receive ultrasound, but the website can receive it normally.

(5) Change to another computer to receive ultrasound, and the situation is the same.

May I ask if you have encountered similar problems and what may be the cause?
send:
2023092022

receive:
2023092011

Improve the library's logging interface

Currently, we can only change the output file stream through a global static call.
Maybe add stuff like log levels, filtering, etc.

See discussion in #51 for some ideas.

font

Please increase font. I use waver in iphone SE
fonts are very tiny

and clear all messages in one button

Memory leak python version

Description

While we were checking to use ggwave in our project, we observed memory leaks using valgrind.

Circumstances

When ggwave is imported in a python script and run against python (valgrind enabled python version), we observed these leaks.

Steps to reproduce

  1. Download Python from the original website
    We used python version 3.9.2

  2. Compile Python using the following flags:
    ./configure --prefix=/check_ggwave/python/ --without-pymalloc --with-pydebug --with-valgrind
    make OPT=-g
    make install

  3. Creating venv using new compiled python in /check_ggwave/python/python3
    python3 -m venv .venv
    . .venv/bin/activate
    pip3 install ggwave

  4. Cloning repo of ggwave and running valgrind on test-ggwave.py:
    test-ggwave: https://github.com/ggerganov/ggwave/blob/master/tests/test-ggwave.py
    valgrind --leak-check=full --log-file="valgrind_report.txt" python test-ggwave.py

Results

For more details please execute the steps above and check your output, here is a summary:

==18560== LEAK SUMMARY:
==18560== definitely lost: 1,800 bytes in 9 blocks
==18560== indirectly lost: 568 bytes in 6 blocks
==18560== possibly lost: 790,082 bytes in 6,445 blocks
==18560== still reachable: 84,547 bytes in 18 blocks
==18560== suppressed: 48 bytes in 1 blocks

Observations

During our tests we observed that there are no leaks using the C or C++ implementation. Feel free to confirm this on your own system(s) as well.

Conclusion

Based on our analysis we suspect that the cause of these leaks lays in the way ggwave's python implementation is generated (bindings).
But this is only an assumption!

How do I generate two-channel audio encoded data

hi,Whether the PCM generated by GGWave is single-track by default,How do I generate two-channel audio encoded data?Whether the use of two-channel playback will affect the codec effect,thanks

mesh

please add mesh functions, resend data to next node. like meshtastic (why not put this same protocol? every walkie talkie can send message trought this)

Short transmissions fail

Sending strings less than 4 chars from IOS ggwaveapp to command line (using python binding) fail, 4 chars and above work just fine.

ggwave-from-file with empty results on non-48kHz files

When using the ggwave-to-file binary, there is a flag for changing the sample rate of the output, -s.
I would expect the corresponding ggwave-from-file binary to be able to work with the new sample rate. It does not though and produces empty results.
It appears from my superficial testing that ggwave-from-file only supports file sampled with 48kHz.
I don't understand why, because for example the file generated below contains only frequencies of below 10 kHz and no information is missing in the audio file itself, when its sampled at a lower rate.

What I did:

./ggwave-to-file -s44100 -fout.wav -> then typed "abc"
-/ggwave-from-file out.wav
The output looks like this:

Usage: ./ggwave-from-file audio.wav [-lN] [-d]
    -lN - fixed payload length of size N, N in [1, 64]
    -d  - use Direct Sequence Spread (DSS)

[+] Number of channels: 1
[+] Sample rate: 44100
[+] Bits per sample: 16
[+] Total samples: 47041
[+] Decoding .. 


[+] Done

Python - TypeError: encode() got an unexpected keyword argument 'txProtocol'

I installed the Python library 'ggwave' via 'pip' (on Python 3.8.5 on Ubuntu).
The library works for the most part - I was able to send and receive (and even have two devices have a 'conversation' - which was fun ;-) )

But the example code doesn't work - seems unable to select the protocol?

The following code fails:

waveform = ggwave.encode("hello python", txProtocol = 1, volume = 20)

With:

TypeError: encode() got an unexpected keyword argument 'txProtocol'

Removing that named keyword "txProtocol" gets rid of the error.

waveform = ggwave.encode("hello python",volume = 20)

Thanks - great project by the way!
Cheers

React Native

Hi, I'm wondering if it's possible to use the ggwave in React Native and if there is an exemple of it!

ggwave not installing on fedora linux with `pip install ggwave'

So I keep getting this error when trying to install ggwave with `pip install ggwave' on my Fedora Linux machine but running the same command on Linux Mint on my brothers laptop installs fine...
I really need this module to work for me since it seems to be one of a kind in the python world roigh now and I do not have the technical skill to write my own right now...

❯ pip install ggwave
Collecting ggwave
  Downloading ggwave-0.4.2.tar.gz (76 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 76.9/76.9 kB 560.2 kB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: ggwave
  Building wheel for ggwave (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for ggwave (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [464 lines of output]
      running bdist_wheel
      running build
      running build_ext
      building 'ggwave' extension
      creating build
      creating build/temp.linux-x86_64-cpython-312
      creating build/temp.linux-x86_64-cpython-312/ggwave
      creating build/temp.linux-x86_64-cpython-312/ggwave/src
      gcc -fno-strict-overflow -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -fexceptions -fcf-protection -fexceptions -fcf-protection -fexceptions -fcf-protection -fPIC -Iggwave/include -Iggwave/include/ggwave -I/home/ace/Documents/ggwave/include -I/usr/include/python3.12 -c ggwave.bycython.cpp -o build/temp.linux-x86_64-cpython-312/ggwave.bycython.o -O3 -std=c++11
      ggwave.bycython.cpp: In function ‘PyObject* __pyx_pf_6ggwave_2init(PyObject*, PyObject*)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1607:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1607 |     __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      In file included from /usr/include/python3.12/dictobject.h:90,
                       from /usr/include/python3.12/Python.h:61,
                       from ggwave.bycython.cpp:6:
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1607:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1607 |     __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1607:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1607 |     __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘PyObject* __pyx_pf_6ggwave_6encode(PyObject*, PyObject*, PyObject*, PyObject*, PyObject*)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1948:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1948 |     __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1948:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1948 |     __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1948:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1948 |     __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1950:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1950 |     __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1950:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1950 |     __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:1950:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       1950 |     __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_getDefaultParameters); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 34, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:2071:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       2071 |     __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_free); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:2071:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       2071 |     __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_free); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1034:43: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1034 |     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
            |                                           ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:2071:5: note: in expansion of macro ‘__Pyx_GetModuleGlobalName’
       2071 |     __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_free); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘uint64_t __Pyx_get_tp_dict_version(PyObject*)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4697:27: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4697 |     return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0;
            |                           ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4697:27: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4697 |     return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0;
            |                           ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4697:27: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4697 |     return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0;
            |                           ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘uint64_t __Pyx_get_object_dict_version(PyObject*)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4709:36: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4709 |     return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0;
            |                                    ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4709:36: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4709 |     return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0;
            |                                    ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:4709:36: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4709 |     return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0;
            |                                    ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘int __Pyx_object_dict_version_matches(PyObject*, uint64_t, uint64_t)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:890:43: note: in definition of macro ‘unlikely’
        890 |   #define unlikely(x) __builtin_expect(!!(x), 0)
            |                                           ^
      ggwave.bycython.cpp:4713:56: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4713 |     if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict)))
            |                                                        ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:890:43: note: in definition of macro ‘unlikely’
        890 |   #define unlikely(x) __builtin_expect(!!(x), 0)
            |                                           ^
      ggwave.bycython.cpp:4713:56: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4713 |     if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict)))
            |                                                        ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:890:43: note: in definition of macro ‘unlikely’
        890 |   #define unlikely(x) __builtin_expect(!!(x), 0)
            |                                           ^
      ggwave.bycython.cpp:4713:56: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       4713 |     if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict)))
            |                                                        ^~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘PyObject* __Pyx__GetModuleGlobalName(PyObject*, uint64_t*, PyObject**)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1008:21: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1008 |     (version_var) = __PYX_GET_DICT_VERSION(dict);\
            |                     ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:4730:5: note: in expansion of macro ‘__PYX_UPDATE_DICT_CACHE’
       4730 |     __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
            |     ^~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1008:21: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1008 |     (version_var) = __PYX_GET_DICT_VERSION(dict);\
            |                     ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:4730:5: note: in expansion of macro ‘__PYX_UPDATE_DICT_CACHE’
       4730 |     __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
            |     ^~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1008:21: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1008 |     (version_var) = __PYX_GET_DICT_VERSION(dict);\
            |                     ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:4730:5: note: in expansion of macro ‘__PYX_UPDATE_DICT_CACHE’
       4730 |     __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
            |     ^~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘void __Pyx_Raise(PyObject*, PyObject*, PyObject*, PyObject*)’:
      ggwave.bycython.cpp:5375:36: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘curexc_traceback’
       5375 |         PyObject* tmp_tb = tstate->curexc_traceback;
            |                                    ^~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5378:21: error: ‘PyThreadState’ {aka ‘struct _ts’} has no member named ‘curexc_traceback’
       5378 |             tstate->curexc_traceback = tb;
            |                     ^~~~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘int __Pyx_CLineForTraceback(PyThreadState*, int)’:
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1013:16: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1013 |     if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\
            |                ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1013:16: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1013 |     if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\
            |                ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:889:43: note: in definition of macro ‘likely’
        889 |   #define likely(x)   __builtin_expect(!!(x), 1)
            |                                           ^
      ggwave.bycython.cpp:1013:16: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1013 |     if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\
            |                ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1017:30: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1017 |         __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\
            |                              ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1017:30: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1017 |         __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\
            |                              ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1006:65: warning: ‘PyDictObject::ma_version_tag’ is deprecated [-Wdeprecated-declarations]
       1006 | #define __PYX_GET_DICT_VERSION(dict)  (((PyDictObject*)(dict))->ma_version_tag)
            |                                                                 ^~~~~~~~~~~~~~
      ggwave.bycython.cpp:1017:30: note: in expansion of macro ‘__PYX_GET_DICT_VERSION’
       1017 |         __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\
            |                              ^~~~~~~~~~~~~~~~~~~~~~
      ggwave.bycython.cpp:5531:9: note: in expansion of macro ‘__PYX_PY_DICT_LOOKUP_IF_MODIFIED’
       5531 |         __PYX_PY_DICT_LOOKUP_IF_MODIFIED(
            |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      /usr/include/python3.12/cpython/dictobject.h:22:34: note: declared here
         22 |     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
            |                                  ^~~~~~~~~~~~~~
      ggwave.bycython.cpp: In function ‘void __Pyx_AddTraceback(const char*, int, int, const char*)’:
      ggwave.bycython.cpp:452:62: error: invalid use of incomplete type ‘PyFrameObject’ {aka ‘struct _frame’}
        452 |   #define __Pyx_PyFrame_SetLineNumber(frame, lineno)  (frame)->f_lineno = (lineno)
            |                                                              ^~
      ggwave.bycython.cpp:5722:5: note: in expansion of macro ‘__Pyx_PyFrame_SetLineNumber’
       5722 |     __Pyx_PyFrame_SetLineNumber(py_frame, py_line);
            |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
      In file included from /usr/include/python3.12/Python.h:42:
      /usr/include/python3.12/pytypedefs.h:22:16: note: forward declaration of ‘PyFrameObject’ {aka ‘struct _frame’}
         22 | typedef struct _frame PyFrameObject;
            |                ^~~~~~
      ggwave.bycython.cpp: In function ‘int __Pyx_PyInt_As_int(PyObject*)’:
      ggwave.bycython.cpp:5891:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       5891 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp:5946:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       5946 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp: In function ‘ggwave_SampleFormat __Pyx_PyInt_As_ggwave_SampleFormat(PyObject*)’:
      ggwave.bycython.cpp:6087:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6087 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp:6142:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6142 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp: In function ‘ggwave_Instance __Pyx_PyInt_As_ggwave_Instance(PyObject*)’:
      ggwave.bycython.cpp:6321:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6321 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp:6376:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6376 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp: In function ‘ggwave_ProtocolId __Pyx_PyInt_As_ggwave_ProtocolId(PyObject*)’:
      ggwave.bycython.cpp:6517:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6517 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp:6572:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6572 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp: In function ‘long int __Pyx_PyInt_As_long(PyObject*)’:
      ggwave.bycython.cpp:6751:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6751 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp:6806:55: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       6806 |             const digit* digits = ((PyLongObject*)x)->ob_digit;
            |                                                       ^~~~~~~~
      ggwave.bycython.cpp: In function ‘Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*)’:
      ggwave.bycython.cpp:7235:47: error: ‘PyLongObject’ {aka ‘struct _longobject’} has no member named ‘ob_digit’
       7235 |     const digit* digits = ((PyLongObject*)b)->ob_digit;
            |                                               ^~~~~~~~
      error: command '/usr/bin/gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for ggwave
Failed to build ggwave
ERROR: Could not build wheels for ggwave, which is required to install pyproject.toml-based projects

C library ggwave_decode, no bounds checking

ggwave_decode doesn't accept a size parameter for the output buffer, nor does it honor the gParam.payloadLength parameter, and will write out of bounds beyond the memory given to it.

ppp

Meybe creating a ppp

every laptop and any radios (like baofeng) will be generaly irc server ;-)

question: how about using a Goertzel filter?

I was wondering, did you try using a Goertzel filter? That allows you to compute the power of a single frequency, that is what is used to detect the DTMF tones. This would spare you having to compute the FFT.

Final config for TxProtocols.

Thank you Gwave team, your library is very helpful to me.
However when I use it, I'm noticing that TxProtocols is final in ggwave.h
With default parameters, are these the best parameters? should i edit it or not?
image

Android

Is there any javascript for android or can I find any source code for your Android app?
It will be very helpful to find one

arduino-rx yields garbled data

Hello Georgi!
My name is Xavier from Melbourne, Australia, and I'm interested in the data-over-sound space.

I've just received my Arduino Nano RP2040 connect and loaded your arduino-rx example code.

Some environmental info:

  • There's no display, button or speaker connected
  • DISPLAY_OUTPUT is not defined

Issue description

examples/arduino-rx shows garbled data when sent a message from waver.

This has been tested with both the waver website and android app. Both are setup to transmit [MT] Fastest. The Arduino is set to receive GGWAVE_PROTOCOL_MT_FASTEST.

Steps to reproduce the issue

  1. Open https://waver.ggerganov.com/ and change TX protocol to MT Fastest, and Fixed-length to true, and 16 bytes
  2. Upload https://github.com/ggerganov/ggwave/blob/master/examples/arduino-rx/arduino-rx.ino onto the RP2040
  3. Open serial monitor - set to 57600
  4. Send the message 'test' using waver

What's the expected result?

Output msg: test

What's the actual result?

Output: msg: ⸮⸮⸮⸮�⸮⸮⸮Eu⸮.�2J_
HEX: E2 FA C7 DB 1B 91 DE C5 45 75 E8 2E 0F 32 4A 5F

Additional details / screenshot

I've been looking through the source code for a day or so without any luck. Do you have any ideas of what might be wrong?
Thanks,
Xavier

ggwave.js doesn't have much options like waver.js

I am trying to receive a message on the web page (https://github.com/ggerganov/ggwave/blob/master/examples/arduino-rx-web/index-tmpl.html) without any success.

it works great with the waver android app using the following settings in screenshots.

photo1662395027 (1)
photo1662395027

But I could not find the same settings in ggwave.js. Please pay attention to the following console warning "[Deprecation] The ScriptProcessorNode is deprecated. Use AudioWorkletNode instead. (https://bit.ly/audio-worklet)"

ios waver not accessible with voiceover screenreader for blind

hello. recently i installed waver on my iphone, and voiceover says (no items on this window). i am blind. screenreaders cannot read graphical elements without label or non-native graphical interface elements. please read about blind accessibility in general. it's not so difficult.

increasing character limit beyond 140

hello..

Firstly amazing tool..incredibly fast and very responsive. Has been trying to increase the 140 character limit on variable length string(very large say 10,000 characters). But stuck at segmentation fault at various stages. Any guidance will be greatly appreciated.

thanks

Ultrasonic Protocols in .js Examples

Hi There @ggerganov,

I'm developing a web app based on the javascript examples provided here, however I'm not able to receive any messages sent using the ultrasonic protocols. I noticed this was consistent across the .js based examples in the repo. Ultrasonic transfers have been working really well in the Python and C++ versions and with Waver as well. The problem does not appear to be microphone related as I am able to receive ultrasonic messages correctly in Waver on the same device.

Can you tell me if this is a known limitation of the .js binding or if it's something I might be able to fix? I'm not a super confident .js developer so I figured I'd ask before digging in too much.

Basing my initial development on this simple example: https://ggwave-js.ggerganov.com/

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.