Full Code of ggerganov/ggwave for AI

master 8f02c41d88f9 cached
154 files
1.2 MB
382.5k tokens
570 symbols
1 requests
Download .txt
Showing preview only (1,252K chars total). Download the full file or copy to clipboard to get everything.
Repository: ggerganov/ggwave
Branch: master
Commit: 8f02c41d88f9
Files: 154
Total size: 1.2 MB

Directory structure:
gitextract_1zhnvrim/

├── .clang-format
├── .github/
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── CMakeLists.txt
├── LICENSE
├── README-tmpl.md
├── README.md
├── bindings/
│   ├── CMakeLists.txt
│   ├── javascript/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── emscripten.cpp
│   │   ├── ggwave.js
│   │   ├── package-tmpl.json
│   │   └── package.json
│   └── python/
│       ├── .gitignore
│       ├── MANIFEST.in
│       ├── Makefile
│       ├── README-tmpl.rst
│       ├── README.md
│       ├── cggwave.pxd
│       ├── debian/
│       │   ├── changelog
│       │   ├── control
│       │   ├── copyright
│       │   ├── python3-ggwave.docs
│       │   ├── rules
│       │   └── source/
│       │       ├── format
│       │       └── options
│       ├── ggwave.pyx
│       ├── setup-tmpl.py
│       ├── setup.py
│       └── test.py
├── cmake/
│   ├── BuildTypes.cmake
│   ├── GitVars.cmake
│   └── sdl2/
│       └── FindSDL2.cmake
├── examples/
│   ├── CMakeLists.txt
│   ├── arduino-rx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-rx.ino
│   │   └── fritzing-sketch.fzz
│   ├── arduino-rx-web/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-rx-web.cpp
│   │   └── index-tmpl.html
│   ├── arduino-tx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-tx.ino
│   │   └── fritzing-sketch.fzz
│   ├── arduino-tx-obsolete/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── arduino-tx.ino
│   │   └── ggwave.h
│   ├── buttons/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── index-tmpl.html
│   ├── dr_wav.h
│   ├── esp32-rx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── esp32-rx.ino
│   │   └── fritzing-sketch.fzz
│   ├── ggwave-cli/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── main.cpp
│   ├── ggwave-common-sdl2.cpp
│   ├── ggwave-common-sdl2.h
│   ├── ggwave-common.cpp
│   ├── ggwave-common.h
│   ├── ggwave-from-file/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── main.cpp
│   ├── ggwave-js/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── index-tmpl.html
│   ├── ggwave-py/
│   │   ├── README.md
│   │   ├── receive.py
│   │   └── send.py
│   ├── ggwave-rx/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── ggwave-to-file/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── ggwave-to-file-local.py
│   │   ├── ggwave-to-file.php
│   │   ├── ggwave-to-file.py
│   │   └── main.cpp
│   ├── ggwave-wasm/
│   │   ├── CMakeLists.txt
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   ├── main.js
│   │   └── style.css
│   ├── icons_font_awesome.h
│   ├── pfd/
│   │   ├── COPYING
│   │   └── pfd.h
│   ├── r2t2/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   ├── main.js
│   │   ├── r2t2-rx.cpp
│   │   └── style.css
│   ├── rp2040-rx/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── fritzing-sketch.fzz
│   │   ├── mic-analog.cpp
│   │   ├── mic-analog.h
│   │   └── rp2040-rx.ino
│   ├── spectrogram/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   └── style.css
│   ├── third-party/
│   │   ├── CMakeLists.txt
│   │   └── imgui/
│   │       ├── CMakeLists.txt
│   │       └── imgui-extra/
│   │           ├── imgui_impl.cpp
│   │           ├── imgui_impl.h
│   │           ├── imgui_impl_opengl3.cpp
│   │           ├── imgui_impl_opengl3.h
│   │           ├── imgui_impl_sdl.cpp
│   │           └── imgui_impl_sdl.h
│   └── waver/
│       ├── CMakeLists.txt
│       ├── README.md
│       ├── build_timestamp-tmpl.h
│       ├── common.cpp
│       ├── common.h
│       ├── index-tmpl.html
│       ├── interface-emscripten.cpp
│       ├── interface-unix.cpp
│       ├── interface.cpp
│       ├── interface.h
│       ├── main.cpp
│       └── style.css
├── include/
│   └── ggwave/
│       └── ggwave.h
├── media/
│   └── favicons-waver/
│       ├── browserconfig.xml
│       └── manifest.json
├── snap/
│   └── snapcraft.yaml
├── src/
│   ├── CMakeLists.txt
│   ├── fft.h
│   ├── ggwave.cpp
│   └── reed-solomon/
│       ├── LICENSE
│       ├── gf.hpp
│       ├── poly.hpp
│       └── rs.hpp
└── tests/
    ├── CMakeLists.txt
    ├── test-ggwave.c
    ├── test-ggwave.cpp
    ├── test-ggwave.js
    └── test-ggwave.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
---
BasedOnStyle: Google
IndentWidth: '4'
DerivePointerAlignment: false
PointerAlignment: Middle
ColumnLimit: 160
AllowShortFunctionsOnASingleLine: false
AllowShortBlocksOnASingleLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
SpaceAfterCStyleCast: 'true'

...


================================================
FILE: .github/workflows/build.yml
================================================
name: CI
on: [push]

jobs:

    ubuntu-24_04-python3-ggwave-deb:
        runs-on: ubuntu-24.04

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install cython3 build-essential debhelper-compat
                  sudo apt install dh-python python3-all-dev python3-build
                  sudo apt install python3-cogapp python3-venv

            - name: Build Debian package for Python bindings
              run: |
                cd bindings/python
                make deb

    ubuntu-24_04-libggwave-dev-deb:
        runs-on: ubuntu-24.04
        strategy:
            matrix:
                build: [Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install build-essential

            - name: Build Debian package for libggwave
              run: |
                cmake . -DGGWAVE_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build }}
                make
                cpack

            - name: Inspect generated Debian package
              run: |
                dpkg --contents dist/libggwave-dev_*.deb
                dpkg -I dist/libggwave-dev_*.deb
                sha256sum dist/libggwave-dev_*.deb

    ubuntu-24_04-target-deb:
        runs-on: ubuntu-24.04
        strategy:
            matrix:
                build: [Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install cython3 build-essential debhelper-compat
                  sudo apt install dh-python python3-all-dev python3-build
                  sudo apt install python3-cogapp python3-venv

            - name: Build Debian packages
              run: |
                cmake . -DGGWAVE_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build }}
                make deb

            - name: Inspect generated Debian packages
              run: |
                dpkg --contents dist/libggwave*.deb
                dpkg -I dist/libggwave*.deb
                dpkg --contents dist/python3*.deb
                dpkg -I dist/python3*.deb
                sha256sum dist/*.deb

    ubuntu-24_04-gcc:
        runs-on: ubuntu-24.04

        strategy:
            matrix:
                build: [Debug, Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install build-essential xorg-dev libglu1-mesa-dev
                  sudo apt install cmake
                  sudo apt install libsdl2-dev

            - name: Configure
              run: cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }}

            - name: Build
              run: |
                make
                ctest --output-on-failure
                ./bin/test-ggwave-cpp --full

    ubuntu-24_04-python:
        runs-on: ubuntu-24.04

        strategy:
            fail-fast: false
            matrix:
                build: [Release]
                python-version: [3.8.18, 3.9.20, 3.11.11, 3.12.9]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Set up Python ${{ matrix.python-version }}
              uses: actions/setup-python@v2
              with:
                  python-version: ${{ matrix.python-version }}

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install build-essential
                  sudo apt install cmake
                  python3 -m venv venv
                  source venv/bin/activate && pip install setuptools cython cogapp

            - name: Configure
              run: cmake . -DGGWAVE_SUPPORT_PYTHON=ON -DGGWAVE_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build }}

            - name: Build
              run: |
                source venv/bin/activate
                make
                ctest --output-on-failure

    ubuntu-24_04-gcc-sanitized:
        runs-on: ubuntu-24.04

        strategy:
            matrix:
                sanitizer: [ADDRESS, THREAD, UNDEFINED]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install build-essential
                  sudo apt install cmake

            - name: Configure
              run: cmake . -DCMAKE_BUILD_TYPE=Debug -DGGWAVE_BUILD_EXAMPLES=OFF -DGGWAVE_SANITIZE_${{ matrix.sanitizer }}=ON

            - name: Build
              run: |
                make
                ctest --output-on-failure

    ubuntu-24_04-clang:
        runs-on: ubuntu-24.04

        strategy:
            matrix:
                build: [Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  sudo apt update
                  sudo apt install build-essential xorg-dev libglu1-mesa-dev
                  sudo apt install cmake
                  sudo apt install libsdl2-dev

            - name: Configure
              run: cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }} -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang

            - name: Build
              run: |
                make
                ctest --output-on-failure

    macOS-latest:
        runs-on: macOS-latest

        strategy:
            matrix:
                build: [Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                  brew update
                  brew install sdl2

            - name: Configure
              run: cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }}

            - name: Build
              run: |
                make
                ctest --output-on-failure

    emscripten:
        runs-on: ubuntu-24.04

        strategy:
            matrix:
                build: [Release]

        steps:
            - name: Clone
              uses: actions/checkout@v1
              with:
                  submodules: recursive

            - name: Dependencies
              run: |
                wget -q https://github.com/emscripten-core/emsdk/archive/master.tar.gz
                tar -xvf master.tar.gz
                emsdk-master/emsdk update
                emsdk-master/emsdk install latest
                emsdk-master/emsdk activate latest

            - name: Configure
              run: echo "tmp"

            - name: Build
              run: |
                pushd emsdk-master
                source ./emsdk_env.sh
                popd
                emcmake cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }}
                make && ctest --output-on-failure

    windows-msys2:
      runs-on: windows-latest
      defaults:
        run:
          shell: msys2 {0}
      strategy:
          matrix:
              build: [Release]
      steps:
        - name: Clone
          uses: actions/checkout@v1
          with:
            submodules: recursive

        - name: Dependencies
          uses: msys2/setup-msys2@v2
          with:
            msystem: MINGW64
            update: true
            install: make mingw-w64-x86_64-cmake mingw-w64-x86_64-dlfcn mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake

        - name: Configure
          run: cmake . -DCMAKE_BUILD_TYPE=${{ matrix.build }} -G "Unix Makefiles"

        - name: Build
          run: |
            ls -alh .
            make
            ctest --output-on-failure


================================================
FILE: .gitignore
================================================
build
build-*
compile_commands.json
.exrc
.clangd
.cache
.vimspector.json
.*.swp
.ycm_extra_conf.py
.DS_Store


================================================
FILE: .gitmodules
================================================
[submodule "examples/third-party/imgui/imgui"]
	path = examples/third-party/imgui/imgui
	url = https://github.com/ocornut/imgui
[submodule "examples/third-party/ggsock"]
	path = examples/third-party/ggsock
	url = https://github.com/ggerganov/ggsock
[submodule "bindings/ios"]
	path = bindings/ios
	url = https://github.com/ggerganov/ggwave-spm


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## [Unreleased]

## [v0.4.0] - 2022-07-05

**This release introduces some breaking changes in the C and C++ API!**

Make sure to read the `ggwave.h` header for more information

- Major refactoring in order to support microcontrollers ([#65](https://github.com/ggerganov/ggwave/pull/65)
- Zero memory allocations during runtime
- Do not include STL headers anymore
- New, low-frequency, mono-tone (MT) protocols suitable for microcontrollers
- Remove code-duplication for some of the examples
- Better FFT implementation
- Less memory usage
- Bug fix in fixed-length payload decoding
- Add Arduino and ESP32 examples
- Support for Direct Sequence Spread (DSS)

## [v0.3.1] - 2021-11-27

- Add interface for changing ggwave's internal logging ([#52](https://github.com/ggerganov/ggwave/pull/52), [#55](https://github.com/ggerganov/ggwave/pull/55))
- Fix out-of-bounds access in `ggwave_decode` ([#53](https://github.com/ggerganov/ggwave/pull/53))
- Add C interface for selecting Rx protocols ([#60](https://github.com/ggerganov/ggwave/pull/60))

## [v0.3.0] - 2021-07-03

- Resampling fixes
- Add `soundMarkerThreshold` parameter ([f4fb02d](https://github.com/ggerganov/ggwave/commit/f4fb02d5d4cfd6c1021d73b55a0e52ac9d3dbdfa))
- Sampling rates are now consistently represented as float instead of int
- Add option to query the generated tones ([ba87a65](https://github.com/ggerganov/ggwave/commit/ba87a651e3e27ce3fa9a85d53ca988a0cedd2e46))
- Fix python build on Windows ([d73b184](https://github.com/ggerganov/ggwave/commit/d73b18426bf0df0e610c31c948e0ddf9a0784073))

## [v0.2.0] - 2021-02-20

- Supported sampling rates: 6kHz - 96kHz
- Variable-length payloads
- Fixed-length payloads (no sound markers emitted)
- Reed-Solomon based ECC
- Ultrasound support

[unreleased]: https://github.com/ggerganov/ggwave/compare/ggwave-v0.4.0...HEAD
[v0.4.0]: https://github.com/ggerganov/ggwave/releases/tag/ggwave-v0.4.0
[v0.3.1]: https://github.com/ggerganov/ggwave/releases/tag/ggwave-v0.3.1
[v0.3.0]: https://github.com/ggerganov/ggwave/releases/tag/ggwave-v0.3.0
[v0.2.0]: https://github.com/ggerganov/ggwave/releases/tag/ggwave-v0.2.0


================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required (VERSION 3.10)
project(ggwave VERSION 0.4.2)

set(GGWAVE_VERSION_PYTHON 0.4.2)

set(CMAKE_EXPORT_COMPILE_COMMANDS "on")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    set(GGWAVE_STANDALONE ON)
    include(cmake/GitVars.cmake)
    include(cmake/BuildTypes.cmake)

    # configure project version
    configure_file(${CMAKE_SOURCE_DIR}/README-tmpl.md                        ${CMAKE_SOURCE_DIR}/README.md @ONLY)
    configure_file(${CMAKE_SOURCE_DIR}/bindings/python/setup-tmpl.py         ${CMAKE_SOURCE_DIR}/bindings/python/setup.py @ONLY)
    configure_file(${CMAKE_SOURCE_DIR}/bindings/javascript/package-tmpl.json ${CMAKE_SOURCE_DIR}/bindings/javascript/package.json @ONLY)
    configure_file(${CMAKE_SOURCE_DIR}/bindings/ios/Makefile-tmpl            ${CMAKE_SOURCE_DIR}/bindings/ios/Makefile @ONLY)
else()
    set(GGWAVE_STANDALONE OFF)
endif()

if (EMSCRIPTEN)
    set(GGWAVE_SUPPORT_SDL2_DEFAULT ON)
    set(BUILD_SHARED_LIBS_DEFAULT OFF)

    option(GGWAVE_WASM_SINGLE_FILE "ggwave: embed WASM inside the generated ggwave.js" ON)
else()
    set(GGWAVE_SUPPORT_SDL2_DEFAULT ON)
    if (WIN32)
        set(BUILD_SHARED_LIBS_DEFAULT OFF)
    else()
        set(BUILD_SHARED_LIBS_DEFAULT ON)
    endif()
endif()

# options

option(BUILD_SHARED_LIBS              "ggwave: build shared libs" ${BUILD_SHARED_LIBS_DEFAULT})
option(USE_FINDSDL2                   "ggwave: use the FindSDL2.cmake script" OFF)

option(GGWAVE_ALL_WARNINGS            "ggwave: enable all compiler warnings" ON)
option(GGWAVE_ALL_WARNINGS_3RD_PARTY  "ggwave: enable all compiler warnings in 3rd party libs" ON)

option(GGWAVE_SANITIZE_THREAD         "ggwave: enable thread sanitizer" OFF)
option(GGWAVE_SANITIZE_ADDRESS        "ggwave: enable address sanitizer" OFF)
option(GGWAVE_SANITIZE_UNDEFINED      "ggwave: enable undefined sanitizer" OFF)

option(GGWAVE_SUPPORT_SDL2            "ggwave: support for libSDL2" ${GGWAVE_SUPPORT_SDL2_DEFAULT})
option(GGWAVE_SUPPORT_PYTHON          "ggwave: support for python" OFF)
option(GGWAVE_SUPPORT_SWIFT           "ggwave: support for swift" OFF)

option(GGWAVE_BUILD_TESTS             "ggwave: build examples" ${GGWAVE_STANDALONE})
option(GGWAVE_BUILD_EXAMPLES          "ggwave: build examples" ${GGWAVE_STANDALONE})

# sanitizers

if (GGWAVE_SANITIZE_THREAD)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
endif()

if (GGWAVE_SANITIZE_ADDRESS)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -D_GLIBCXX_DEBUG")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -D_GLIBCXX_DEBUG")
endif()

if (GGWAVE_SANITIZE_UNDEFINED)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
endif()

# dependencies

# main

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if (GGWAVE_ALL_WARNINGS)
    if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
    else()
        # todo : windows
    endif()
endif()

add_subdirectory(src)
add_subdirectory(bindings)

if (GGWAVE_BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

if (GGWAVE_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()



set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
set(CPACK_DEB_COMPONENT_INSTALL YES)
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/ggerganov/ggwave")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Georgi Gerganov")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS YES)
set(CPACK_GENERATOR DEB)
SET(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/dist")
set(CPACK_PACKAGE_CONTACT "ggerganov@gmail.com")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Tiny data-over-sound library")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_PACKAGE_NAME "libggwave-dev")
set(CPACK_PACKAGE_VENDOR "ggwave")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_STRIP_FILES YES)
set(CPACK_VERBATIM_VARIABLES YES)
include(CPack)

set(DEB_PYTHON_BUILD_DIR "${CMAKE_SOURCE_DIR}/bindings/python/")
set(DEB_PYTHON_OUTPUT_FILE_PREFIX "${DEB_PYTHON_BUILD_DIR}/dist")

set(ENV{SOURCE_DATE_EPOCH} "0")
execute_process(
  COMMAND git log -1 --pretty=%ct
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
  TIMEOUT 1
  OUTPUT_VARIABLE SOURCE_DATE_EPOCH
  OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(ENV{SOURCE_DATE_EPOCH} ${SOURCE_DATE_EPOCH})

add_custom_target(deb_python_binding
    COMMAND cd ${DEB_PYTHON_BUILD_DIR} && make deb
    COMMENT "Building Debian package for Python binding"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

add_custom_target(deb_c_library
    COMMAND SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} cpack 
    COMMENT "Building Debian package for C library"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

add_custom_target(deb_python_move
    COMMAND mv ${DEB_PYTHON_OUTPUT_FILE_PREFIX}/*.deb ${CPACK_OUTPUT_FILE_PREFIX}/
    COMMENT "Moving Debian package for Python binding into ${CPACK_OUTPUT_FILE_PREFIX}/"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    DEPENDS deb_python_binding deb_c_library
)

add_custom_target(deb
    COMMAND sha256sum ${CPACK_OUTPUT_FILE_PREFIX}/* 
    COMMENT "Debian package sha256 hashes"
    DEPENDS deb_c_library deb_python_binding deb_python_move
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

add_custom_command(TARGET deb
    POST_BUILD
    COMMAND ls -alh ${CPACK_OUTPUT_FILE_PREFIX}/* 
    COMMENT "SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}"
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Georgi Gerganov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README-tmpl.md
================================================
# ggwave

[![Actions Status](https://github.com/ggerganov/ggwave/workflows/CI/badge.svg)](https://github.com/ggerganov/ggwave/actions)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![ggwave badge][changelog-badge]][changelog]
[![pypi](https://img.shields.io/pypi/v/ggwave.svg)](https://pypi.org/project/ggwave/)
[![npm](https://img.shields.io/npm/v/ggwave.svg)](https://www.npmjs.com/package/ggwave/)

Tiny data-over-sound library.

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

<a href="https://youtu.be/S2YdGefZiy4"><img width="100%" src="media/ggwave0.gif"></img></a>

<a href="https://user-images.githubusercontent.com/1991296/161401690-013023ba-1d21-4fb7-8d7f-9953f51c1e5b.mp4"><img width="100%" src="https://user-images.githubusercontent.com/1991296/109401710-d7d3d880-7958-11eb-9b7e-364be0b4cf55.gif"></img></a>

<a href="https://youtu.be/Zcgf77T71QM"><img width="100%" src="media/waver-preview1.gif"></img></a>

https://user-images.githubusercontent.com/1991296/166411509-5e1b9bcb-3655-40b1-9dc3-9bec72889dcf.mp4

https://user-images.githubusercontent.com/1991296/168469004-aeb9b9fe-cf81-4db7-b602-62e4ae659341.mp4

<a href="https://youtu.be/aj_GLBtU3Vw"><img width="100%" src="https://user-images.githubusercontent.com/1991296/177214041-26456254-d4b5-425b-bc57-48bcfc8f816e.png"></img></a>

## 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:

- **Serverless, one-to-many broadcast**
  - [wave-share](https://github.com/ggerganov/wave-share) - file sharing through sound
- **Internet of Things**
  - [esp32-rx](https://github.com/ggerganov/ggwave/tree/master/examples/esp32-rx), [arduino-rx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-rx), [rp2040-rx](https://github.com/ggerganov/ggwave/tree/master/examples/rp2040-rx), [arduino-tx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-tx) - Sand and receive sound data on microcontrollers
  - [r2t2](https://github.com/ggerganov/ggwave/tree/master/examples/r2t2) - Transmit data with the PC speaker
  - [buttons](https://github.com/ggerganov/ggwave/tree/master/examples/buttons) - Record and send commands via [Talking buttons](https://github.com/ggerganov/ggwave/discussions/27)
- **Audio QR codes**
  - [[Twitter]](https://twitter.com/ggerganov/status/1509558482567057417) - Broadcast your clipboard to nearby devices
- **Device pairing**
- **Authorization**

## Try it out

You can easily test the library using the free [waver](https://github.com/ggerganov/ggwave/tree/master/examples/waver) application which is available on the following platforms:

<a href="https://apps.apple.com/us/app/waver-data-over-sound/id1543607865?itsct=apps_box&amp;itscg=30200&ign-itsct=apps_box#?platform=iphone" style="display: inline-block; overflow: hidden; border-radius: 13px; width: 250px; height: 83px;"><img height="60px" src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/white/en-US?size=250x83&amp;releaseDate=1607558400&h=8e5fafc57929918f684abc83ff8311ef" alt="Download on the App Store"></a>
<a href='https://play.google.com/store/apps/details?id=com.ggerganov.Waver&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://i.imgur.com/BKDCbKv.png' height="60px"/></a>
<a href="https://snapcraft.io/waver">
<img alt="Get it from the Snap Store" src="https://snapcraft.io/static/images/badges/en/snap-store-black.svg" height="60px"/>
</a>

### Browser demos

  - https://waver.ggerganov.com
  - https://ggwave.ggerganov.com
  - https://ggwave-js.ggerganov.com

### [HTTP service](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-to-file/README.md#http-service)

  ```bash
  # 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)](https://en.wikipedia.org/wiki/Frequency-shift_keying) 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](https://github.com/ggerganov/ggwave/blob/master/src/reed-solomon). 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](https://github.com/ggerganov/ggwave/discussions/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](https://github.com/ggerganov/ggwave/blob/master/examples/) folder contains several sample applications of the library:


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

Other projects using **ggwave** or one of its prototypes:

- [wave-gui](https://github.com/ggerganov/wave-gui) - a GUI for exploring different modulation protocols
- [wave-share](https://github.com/ggerganov/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)

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

# running
./bin/ggwave-cli
```

#### Local Debian packages

Build reproducible `libggwave-dev` and `python3-ggwave` Debian packages:
```bash
# Fetch source
git clone https://github.com/ggerganov/ggwave --recursive
cd ggwave

# Configure
cmake . -DGGWAVE_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=Release

# Build
make deb

# Install
sudo dpkg -i dist/*.deb
```

### Emscripten

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

### Python

```bash
pip install ggwave
```

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

### Node.js

```bash
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](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/waver)

### Linux

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

### Mac OS

  ```bash
  brew install ggerganov/ggerganov/waver
  ```

[changelog]: ./CHANGELOG.md
[changelog-badge]: https://img.shields.io/badge/changelog-ggwave%20v@PROJECT_VERSION@-dummy
[license]: ./LICENSE


================================================
FILE: README.md
================================================
# ggwave

[![Actions Status](https://github.com/ggerganov/ggwave/workflows/CI/badge.svg)](https://github.com/ggerganov/ggwave/actions)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![ggwave badge][changelog-badge]][changelog]
[![pypi](https://img.shields.io/pypi/v/ggwave.svg)](https://pypi.org/project/ggwave/)
[![npm](https://img.shields.io/npm/v/ggwave.svg)](https://www.npmjs.com/package/ggwave/)

Tiny data-over-sound library.

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

<a href="https://youtu.be/S2YdGefZiy4"><img width="100%" src="media/ggwave0.gif"></img></a>

<a href="https://user-images.githubusercontent.com/1991296/161401690-013023ba-1d21-4fb7-8d7f-9953f51c1e5b.mp4"><img width="100%" src="https://user-images.githubusercontent.com/1991296/109401710-d7d3d880-7958-11eb-9b7e-364be0b4cf55.gif"></img></a>

<a href="https://youtu.be/Zcgf77T71QM"><img width="100%" src="media/waver-preview1.gif"></img></a>

https://user-images.githubusercontent.com/1991296/166411509-5e1b9bcb-3655-40b1-9dc3-9bec72889dcf.mp4

https://user-images.githubusercontent.com/1991296/168469004-aeb9b9fe-cf81-4db7-b602-62e4ae659341.mp4

<a href="https://youtu.be/aj_GLBtU3Vw"><img width="100%" src="https://user-images.githubusercontent.com/1991296/177214041-26456254-d4b5-425b-bc57-48bcfc8f816e.png"></img></a>

## 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:

- **Serverless, one-to-many broadcast**
  - [wave-share](https://github.com/ggerganov/wave-share) - file sharing through sound
- **Internet of Things**
  - [esp32-rx](https://github.com/ggerganov/ggwave/tree/master/examples/esp32-rx), [arduino-rx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-rx), [rp2040-rx](https://github.com/ggerganov/ggwave/tree/master/examples/rp2040-rx), [arduino-tx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-tx) - Send and receive sound data on microcontrollers
  - [r2t2](https://github.com/ggerganov/ggwave/tree/master/examples/r2t2) - Transmit data with the PC speaker
  - [buttons](https://github.com/ggerganov/ggwave/tree/master/examples/buttons) - Record and send commands via [Talking buttons](https://github.com/ggerganov/ggwave/discussions/27)
- **Audio QR codes**
  - [[Twitter]](https://twitter.com/ggerganov/status/1509558482567057417) - Broadcast your clipboard to nearby devices
- **Device pairing / Contact exchange**
  - [PairSonic](https://github.com/seemoo-lab/pairsonic) - Exchange contact information and public keys with nearby devices
- **Authorization**

## Try it out

You can easily test the library using the free [waver](https://github.com/ggerganov/ggwave/tree/master/examples/waver) application which is available on the following platforms:

<a href="https://apps.apple.com/us/app/waver-data-over-sound/id1543607865?itsct=apps_box&amp;itscg=30200&ign-itsct=apps_box#?platform=iphone" style="display: inline-block; overflow: hidden; border-radius: 13px; width: 250px; height: 83px;"><img height="60px" src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/white/en-US?size=250x83&amp;releaseDate=1607558400&h=8e5fafc57929918f684abc83ff8311ef" alt="Download on the App Store"></a>
<a href='https://play.google.com/store/apps/details?id=com.ggerganov.Waver&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' src='https://i.imgur.com/BKDCbKv.png' height="60px"/></a>
<a href="https://snapcraft.io/waver">
<img alt="Get it from the Snap Store" src="https://snapcraft.io/static/images/badges/en/snap-store-black.svg" height="60px"/>
</a>

### Browser demos

  - https://waver.ggerganov.com
  - https://ggwave.ggerganov.com
  - https://ggwave-js.ggerganov.com

### [HTTP service](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-to-file/README.md#http-service)

  ```bash
  # 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)](https://en.wikipedia.org/wiki/Frequency-shift_keying) 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](https://github.com/ggerganov/ggwave/blob/master/src/reed-solomon). 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](https://github.com/ggerganov/ggwave/discussions/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](https://github.com/ggerganov/ggwave/blob/master/examples/) folder contains several sample applications of the library:


| Example | Description | Audio |
| ------- | ----------- | ----- |
| [ggtag](https://github.com/rgerganov/ggtag) | Sound-programmable e-paper badge | PDM mic |
| [ggwave-rx](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-rx) | Very basic receive-only program | SDL |
| [ggwave-cli](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-cli) | Command line tool for sending/receiving data through sound | SDL |
| [ggwave-wasm](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-wasm) | WebAssembly module for web applications | SDL |
| [ggwave-to-file](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-to-file) | Output a generated waveform to an uncompressed WAV file | - |
| [ggwave-from-file](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-from-file) | Decode a waveform from an uncompressed WAV file | - |
| [waver](https://github.com/ggerganov/ggwave/blob/master/examples/waver) | GUI application for sending/receiving data through sound | SDL |
| [ggwave-py](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-py) | Python examples | PortAudio |
| [ggwave-js](https://github.com/ggerganov/ggwave/blob/master/examples/ggwave-js) | Javascript example | Web Audio API |
| [spectrogram](https://github.com/ggerganov/ggwave/blob/master/examples/spectrogram) | Spectrogram tool | SDL |
| [ggweb-spike](https://gitlab.com/commonsguy/ggweb-spike) | Android example using a `WebView` to wrap `ggwave` into a simple app | WebAudio |
| [buttons](https://github.com/ggerganov/ggwave/blob/master/examples/buttons) | Record and send commands via Talking buttons | Web Audio API |
| [r2t2](https://github.com/ggerganov/ggwave/blob/master/examples/r2t2) | Transmit data through the PC speaker | PC speaker |
| [ggwave-objc](https://github.com/ggerganov/ggwave-objc) | Minimal Objective-C iOS app using ggwave | AudioToolbox |
| [ggwave-java](https://github.com/ggerganov/ggwave-java) | Minimal Java Android app using ggwave | android.media |
| [ggwave-kmm](https://github.com/wooram-yang/ggwave-kmm) | Kotlin Multiplatform Project using ggwave | android.media, javax.sound.sampled |
| [ggwave-fm](https://github.com/rgerganov/ggwave-fm) | Transmit ggwave messages with HackRF | Radio |
| [esp32-rx](https://github.com/ggerganov/ggwave/tree/master/examples/esp32-rx) | Transmit and receive messages using ESP32 | - |
| [rp2040-rx](https://github.com/ggerganov/ggwave/tree/master/examples/rp2040-rx) | Transmit and receive messages using Raspberry Pi Pico (RP2040) | - |
| [arduino-rx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-rx) | Transmit and receive messages using Arduino RP2040 | - |
| [arduino-tx](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-tx) | Transmit messages using Arduino Uno | - |
| [arduino-rx-web](https://github.com/ggerganov/ggwave/tree/master/examples/arduino-rx-web) | Receive messages from Arduino Uno | Web Audio API |

Other projects using **ggwave** or one of its prototypes:

- [wave-gui](https://github.com/ggerganov/wave-gui) - a GUI for exploring different modulation protocols
- [wave-share](https://github.com/ggerganov/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)

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

# running
./bin/ggwave-cli
```

#### Local Debian packages

Build reproducible `libggwave-dev` and `python3-ggwave` Debian packages:
```bash
# Fetch source
git clone https://github.com/ggerganov/ggwave --recursive
cd ggwave

# Configure
cmake . -DGGWAVE_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=Release

# Build
make deb

# Install
sudo dpkg -i dist/*.deb
```

### Emscripten

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

### Python

```bash
pip install ggwave
```

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

### Node.js

```bash
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](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/waver)

### Linux

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

### Mac OS

  ```bash
  brew install ggerganov/ggerganov/waver
  ```

## References

- [Evaluating Acoustic Data Transmission Schemes for Ad-Hoc Communication Between Nearby Smart Devices](https://dl.acm.org/doi/10.1145/3779439)

[changelog]: ./CHANGELOG.md
[changelog-badge]: https://img.shields.io/badge/changelog-ggwave%20v0.4.2-dummy
[license]: ./LICENSE


================================================
FILE: bindings/CMakeLists.txt
================================================
if (EMSCRIPTEN)
    add_subdirectory(javascript)

    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/javascript/publish.log
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/javascript/ggwave.js
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/javascript/package.json
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/javascript
        COMMAND npm publish
        COMMAND touch publish.log
        COMMENT "Publishing npm module v${PROJECT_VERSION}"
        VERBATIM
        )

    add_custom_target(publish-npm
        DEPENDS javascript/publish.log
        )
endif()

if (GGWAVE_SUPPORT_PYTHON)
    file(GLOB_RECURSE GGWAVE_SOURCES "../include/*" "../src/*")

    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/python/ggwave.bycython.cpp
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/python/ggwave
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/Makefile
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/ggwave.pyx
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/cggwave.pxd
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/setup.py
        DEPENDS ${GGWAVE_SOURCES}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/python
        COMMAND make clean
        COMMAND make
        COMMENT "Compiling Python module"
        VERBATIM
        )

    add_custom_target(ggwave-py ALL
        DEPENDS python/ggwave.bycython.cpp
        DEPENDS python/ggwave
        )

    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/python/dist
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/Makefile
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/ggwave.pyx
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/cggwave.pxd
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/python/setup.py
        DEPENDS ${GGWAVE_SOURCES}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/python
        COMMAND make publish
        COMMENT "Publishing Python module v${GGWAVE_VERSION_PYTHON}"
        VERBATIM
        )

    add_custom_target(publish-pypi
        DEPENDS python/dist
        )
endif()

if (GGWAVE_SUPPORT_SWIFT)
    file(GLOB_RECURSE GGWAVE_SOURCES "../include/*" "../src/*")

    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ios/.build
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ios/Makefile
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ios/Package.swift
        DEPENDS ${GGWAVE_SOURCES}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ios
        COMMAND make clean
        COMMAND make build-submodule
        COMMENT "Compiling Swift package"
        VERBATIM
        )

    add_custom_target(ggwave-spm ALL
        DEPENDS ios/.build
        )

    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/ios/publish
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ios/publish-trigger
        DEPENDS ${GGWAVE_SOURCES}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ios
        COMMAND make publish
        COMMENT "Publishing Swift package v${PROJECT_VERSION}"
        VERBATIM
        )

    add_custom_target(publish-spm
        DEPENDS ios/publish
        )
endif()


================================================
FILE: bindings/javascript/.gitignore
================================================
publish.log


================================================
FILE: bindings/javascript/CMakeLists.txt
================================================
set(TARGET libggwave)

add_executable(${TARGET}
    emscripten.cpp
    )

target_link_libraries(${TARGET} PRIVATE
    ggwave
    )

unset(EXTRA_FLAGS)
if (GGWAVE_WASM_SINGLE_FILE)
    set(EXTRA_FLAGS "-s SINGLE_FILE=1")
    message(STATUS "Embedding WASM inside ggwave.js")

    add_custom_command(
        TARGET libggwave POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
        ${CMAKE_BINARY_DIR}/bin/libggwave.js
        ${CMAKE_CURRENT_SOURCE_DIR}/ggwave.js
        )
endif()

set_target_properties(${TARGET} PROPERTIES LINK_FLAGS " \
    --bind \
    -s MODULARIZE=1 \
    -s ALLOW_MEMORY_GROWTH=1 \
    -s EXPORT_NAME=\"'ggwave_factory'\" \
    ${EXTRA_FLAGS} \
    ")


================================================
FILE: bindings/javascript/README.md
================================================
# ggwave

Tiny data-over-sound library.

- Audible and ultrasound transmissions available
- Bandwidth of 8-16 bytes/s (depending on the transmission protocol)
- Robust FSK modulation
- Reed-Solomon based error correction

## Example Usage

```js
var factory = require('ggwave')

factory().then(function(ggwave) {
    // create ggwave instance with default parameters
    var parameters = ggwave.getDefaultParameters();

    parameters.operatingMode |= ggwave.GGWAVE_OPERATING_MODE_USE_DSS;

    var instance = ggwave.init(parameters);
    console.log('instance: ' + instance);

    var payload = 'hello js';

    // generate audio waveform for string "hello js"
    var waveform = ggwave.encode(instance, payload, ggwave.ProtocolId.GGWAVE_PROTOCOL_AUDIBLE_FAST, 10);

    // decode the audio waveform back to text
    var res = ggwave.decode(instance, waveform);

    if (new TextDecoder("utf-8").decode(res) != payload) {
        process.exit(1);
    }
});
```


================================================
FILE: bindings/javascript/emscripten.cpp
================================================
#include "ggwave/ggwave.h"

#include <emscripten.h>
#include <emscripten/bind.h>

EMSCRIPTEN_BINDINGS(ggwave) {
    emscripten::enum_<ggwave_SampleFormat>("SampleFormat")
        .value("GGWAVE_SAMPLE_FORMAT_UNDEFINED", GGWAVE_SAMPLE_FORMAT_UNDEFINED)
        .value("GGWAVE_SAMPLE_FORMAT_U8",        GGWAVE_SAMPLE_FORMAT_U8)
        .value("GGWAVE_SAMPLE_FORMAT_I8",        GGWAVE_SAMPLE_FORMAT_I8)
        .value("GGWAVE_SAMPLE_FORMAT_U16",       GGWAVE_SAMPLE_FORMAT_U16)
        .value("GGWAVE_SAMPLE_FORMAT_I16",       GGWAVE_SAMPLE_FORMAT_I16)
        .value("GGWAVE_SAMPLE_FORMAT_F32",       GGWAVE_SAMPLE_FORMAT_F32)
        ;

    emscripten::enum_<ggwave_ProtocolId>("ProtocolId")
        .value("GGWAVE_PROTOCOL_AUDIBLE_NORMAL",     GGWAVE_PROTOCOL_AUDIBLE_NORMAL)
        .value("GGWAVE_PROTOCOL_AUDIBLE_FAST",       GGWAVE_PROTOCOL_AUDIBLE_FAST)
        .value("GGWAVE_PROTOCOL_AUDIBLE_FASTEST",    GGWAVE_PROTOCOL_AUDIBLE_FASTEST)
        .value("GGWAVE_PROTOCOL_ULTRASOUND_NORMAL",  GGWAVE_PROTOCOL_ULTRASOUND_NORMAL)
        .value("GGWAVE_PROTOCOL_ULTRASOUND_FAST",    GGWAVE_PROTOCOL_ULTRASOUND_FAST)
        .value("GGWAVE_PROTOCOL_ULTRASOUND_FASTEST", GGWAVE_PROTOCOL_ULTRASOUND_FASTEST)
        .value("GGWAVE_PROTOCOL_DT_NORMAL",          GGWAVE_PROTOCOL_DT_NORMAL)
        .value("GGWAVE_PROTOCOL_DT_FAST",            GGWAVE_PROTOCOL_DT_FAST)
        .value("GGWAVE_PROTOCOL_DT_FASTEST",         GGWAVE_PROTOCOL_DT_FASTEST)
        .value("GGWAVE_PROTOCOL_MT_NORMAL",          GGWAVE_PROTOCOL_MT_NORMAL)
        .value("GGWAVE_PROTOCOL_MT_FAST",            GGWAVE_PROTOCOL_MT_FAST)
        .value("GGWAVE_PROTOCOL_MT_FASTEST",         GGWAVE_PROTOCOL_MT_FASTEST)

        .value("GGWAVE_PROTOCOL_CUSTOM_0", GGWAVE_PROTOCOL_CUSTOM_0)
        .value("GGWAVE_PROTOCOL_CUSTOM_1", GGWAVE_PROTOCOL_CUSTOM_1)
        .value("GGWAVE_PROTOCOL_CUSTOM_2", GGWAVE_PROTOCOL_CUSTOM_2)
        .value("GGWAVE_PROTOCOL_CUSTOM_3", GGWAVE_PROTOCOL_CUSTOM_3)
        .value("GGWAVE_PROTOCOL_CUSTOM_4", GGWAVE_PROTOCOL_CUSTOM_4)
        .value("GGWAVE_PROTOCOL_CUSTOM_5", GGWAVE_PROTOCOL_CUSTOM_5)
        .value("GGWAVE_PROTOCOL_CUSTOM_6", GGWAVE_PROTOCOL_CUSTOM_6)
        .value("GGWAVE_PROTOCOL_CUSTOM_7", GGWAVE_PROTOCOL_CUSTOM_7)
        .value("GGWAVE_PROTOCOL_CUSTOM_8", GGWAVE_PROTOCOL_CUSTOM_8)
        .value("GGWAVE_PROTOCOL_CUSTOM_9", GGWAVE_PROTOCOL_CUSTOM_9)
        ;

    emscripten::constant("GGWAVE_OPERATING_MODE_RX",            (int) GGWAVE_OPERATING_MODE_RX);
    emscripten::constant("GGWAVE_OPERATING_MODE_TX",            (int) GGWAVE_OPERATING_MODE_TX);
    emscripten::constant("GGWAVE_OPERATING_MODE_RX_AND_TX",     (int) GGWAVE_OPERATING_MODE_RX | GGWAVE_OPERATING_MODE_TX);
    emscripten::constant("GGWAVE_OPERATING_MODE_TX_ONLY_TONES", (int) GGWAVE_OPERATING_MODE_TX_ONLY_TONES);
    emscripten::constant("GGWAVE_OPERATING_MODE_USE_DSS",       (int) GGWAVE_OPERATING_MODE_USE_DSS);

    emscripten::value_object<ggwave_Parameters>("Parameters")
        .field("payloadLength",        & ggwave_Parameters::payloadLength)
        .field("sampleRateInp",        & ggwave_Parameters::sampleRateInp)
        .field("sampleRateOut",        & ggwave_Parameters::sampleRateOut)
        .field("sampleRate",           & ggwave_Parameters::sampleRate)
        .field("samplesPerFrame",      & ggwave_Parameters::samplesPerFrame)
        .field("soundMarkerThreshold", & ggwave_Parameters::soundMarkerThreshold)
        .field("sampleFormatInp",      & ggwave_Parameters::sampleFormatInp)
        .field("sampleFormatOut",      & ggwave_Parameters::sampleFormatOut)
        .field("operatingMode",        & ggwave_Parameters::operatingMode)
        ;

    emscripten::function("getDefaultParameters", & ggwave_getDefaultParameters);
    emscripten::function("init", & ggwave_init);
    emscripten::function("free", & ggwave_free);

    emscripten::function("encode", emscripten::optional_override(
                    [](ggwave_Instance instance,
                       const std::string & data,
                       ggwave_ProtocolId protocolId,
                       int volume) {
                        auto n = ggwave_encode(instance, data.data(), data.size(), protocolId, volume, nullptr, 1);

                        // TODO: how to return the waveform data?
                        //       for now using this static vector and returning a pointer to it
                        static std::vector<char> result(n);
                        result.resize(n);

                        int nActual = ggwave_encode(instance, data.data(), data.size(), protocolId, volume, result.data(), 0);

                        // printf("n = %d, nActual = %d\n", n, nActual);
                        return emscripten::val(emscripten::typed_memory_view(nActual, result.data()));
                    }));

    emscripten::function("decode", emscripten::optional_override(
                    [](ggwave_Instance instance,
                       const std::string & data) {
                        // TODO: how to return the result?
                        //       again using a static array and returning a pointer to it
                        static char output[256];

                        auto n = ggwave_decode(instance, data.data(), data.size(), output);

                        if (n > 0) {
                            return emscripten::val(emscripten::typed_memory_view(n, output));
                        }

                        return emscripten::val(emscripten::typed_memory_view(0, output));
                    }));

    emscripten::function("disableLog", emscripten::optional_override(
                    []() {
                        ggwave_setLogFile(NULL);
                    }));

    emscripten::function("enableLog", emscripten::optional_override(
                    []() {
                        ggwave_setLogFile(stderr);
                    }));

    emscripten::function("rxToggleProtocol", emscripten::optional_override(
                    [](ggwave_ProtocolId protocolId,
                       int state) {
                        ggwave_rxToggleProtocol(protocolId, state);
                    }));

    emscripten::function("txToggleProtocol", emscripten::optional_override(
                    [](ggwave_ProtocolId protocolId,
                       int state) {
                        ggwave_txToggleProtocol(protocolId, state);
                    }));

    emscripten::function("rxProtocolSetFreqStart", emscripten::optional_override(
                    [](ggwave_ProtocolId protocolId,
                       int freqStart) {
                        ggwave_rxProtocolSetFreqStart(protocolId, freqStart);
                    }));

    emscripten::function("txProtocolSetFreqStart", emscripten::optional_override(
                    [](ggwave_ProtocolId protocolId,
                       int freqStart) {
                        ggwave_txProtocolSetFreqStart(protocolId, freqStart);
                    }));

    emscripten::function("rxDurationFrames", emscripten::optional_override(
                    [](ggwave_Instance instance) {
                        return ggwave_rxDurationFrames(instance);
                    }));
}


================================================
FILE: bindings/javascript/ggwave.js
================================================

var ggwave_factory = (() => {
  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
  if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
  return (
function(moduleArg = {}) {

var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]"}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="data:application/octet-stream;base64,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AABFDQBBASECA0AgAkH/AXEhGUEAIQIgGQRAA0AgACgCQCgCACAALwE8aiACIAtqQf8BcWoiBQJ/QQAgBygCCCgCACAHLwEEaiACai0AACIERQ0AGkEAIAAoApQBKAIAIAAvAZABaiALai0AACIBRQ0AGiABQdApai0AACAEQdApai0AAGpB0CtqLQAACyAFLQAAczoAACACQQFqIgIgBy0AACIBSQ0ACyAALQCMASEEIAEhAgsgC0EBaiILIARJDQALCyAAIAlBAmo6AEQgACgCTCgCACAALwFIakEAIAAtAEYQGxogACgCTCgCACAALwFIakEBOgAAIAAoAkAoAgAgAC8BPGoiAiAAKAJwKAIAIAAvAWxqIgFHBEAgASACIAAtADgQGhoLIAAgAC0AOCICOgBoIAAtADgiBSAALQBEIgFrQQFqIgdBAEoEQEEAIQIDQAJAIAAoAnAoAgAgAC8BbGogAmotAAAiBEUNACABQQJJDQBBASEFA0AgACgCTCgCACAALwFIaiAFai0AACIHBEAgACgCcCgCACAALwFsaiACIAVqQf8BcWoiASABLQAAIARB0ClqLQAAIAdB0ClqLQAAakHQK2otAABzOgAAIAAtAEQhAQsgBUEBaiIFIAFJDQALIAAtADghBQsgAkEBaiICIAVB/wFxIAFrQQFqIgdIDQALIAAtAGghAgsgACgCcCgCACAALwFsaiIBIAEgB2ogAkH/AXEgB2sQMxogACAALQBoIAdrOgBoIAAgAC0AaCIBOgDIASABQQFrwCICQQBOBEBBACEGA0AgACgC0AEoAgAgAC8BzAFqIAZqIAAoAnAoAgAgAC8BbGogAkH/AXFqLQAAOgAAIAJBAWshAiAGQQFqIgYgAUcNAAsLIABBADoAOCAALQC8AQRAQQAhAgNAIAAoAsQBKAIAIAAvAcABaiACai0AACEEIAAoAkAoAgAhByAAIAAtADgiAUEBajoAOCABIAcgAC8BPGpqIARBf3NBACAEGyIBQX9zQQAgAUH/AXEbQf8BcUHQK2otAAA6AAAgAkEBaiICIAAtALwBSQ0ACwsgACgCWCgCACAALwFUakEAIAAtAFIQGxogACAILQAAIgI6AFAgAC0AOCIGBEBBACEMA0AgACgCQCgCACAALwE8aiAMai0AACEaIABBADoARCAaQdApai0AAEH/AXNB0CtqLQAAIQpBASECAkAgBkH/AXFFDQBBACECA0AgAiAMRwRAIAAoAkAoAgAgAC8BPGogAmotAAAiAQR/IAFB0ClqLQAAIApB0ClqLQAAakHQK2otAAAFQQALIQQgACgCTCgCACEHIAAgAC0ARCIBQQFqOgBEIAEgByAALwFIamogBEEBczoAACAALQA4IQYLIAJBAWoiAiAGQf8BcUkNAAtBASECIAAtAEQiBEUNACAAKAJMKAIAIAAvAUhqIQdBACEGA0ACf0EAIAJB/wFxIgJFDQAaQQAgBiAHai0AACIBRQ0AGiABQdApai0AACACQdApai0AAGpB0CtqLQAACyECIAZBAWoiBiAERw0ACwsgACgCcCgCACAALwFsaiILLQAAIQUCQCAALQBoIgdBAkkNAEEBIQYgB0EBayIBQQFxIRwgB0ECRwRAIAFBfnEhBEEAIQ0DQCAFQf8BcSIBBH8gCkHQKWotAAAgAUHQKWotAABqQdArai0AAAVBAAsgBiALai0AAHNB/wFxIgEEfyAKQdApai0AACABQdApai0AAGpB0CtqLQAABUEACyEHIAZBAWohGyAGQQJqIQYgGyALai0AACAHcyEFIA1BAmoiDSAERw0ACwsgHEUNACAFQf8BcSIBBH8gCkHQKWotAAAgAUHQKWotAABqQdArai0AAAVBAAsgBiALai0AAHMhBQsgACgCrAEoAgAgAC8BqAFqIAxqLQAAIAAoAlgoAgAgAC8BVGpqIAVB/wFxIgcEfyAAKAJAKAIAIAAvATxqIAxqLQAAQdApai0AACIBQQAgAUH/AUcbQf8BcUHQK2otAABB0ClqLQAAIAdB0ClqLQAAakHQK2otAABB0ClqLQAAIAJB/wFxQdApai0AAGtB/wFqQf//A3FB/wFwQdArai0AAAVBAAs6AAAgDEEBaiIMIAAtADgiBkkNAAsgAC0AUCECCyAAIAgtAAAiByACQf8BcSIBIAEgB0kbIgE6ACBBACECIAAoAigoAgAgAC8BJGpBACABEBsaIAgtAAAiBgRAA0AgACgCKCgCACAALwEkaiAALQAgIAIgBmtqQf8BcWogCCgCCCgCACAILwEEaiACai0AADoAACACQQFqIgIgCC0AACIGSQ0ACwsgAC0AUCIGBEBBACECA0AgACgCKCgCACAALwEkaiAALQAgIAIgBmtqQf8BcWoiASABLQAAIAAoAlgoAgAgAC8BVGogAmotAABzOgAAIAJBAWoiAiAALQBQIgZJDQALCwsgACAOOgAgIAMgACgCKCgCACAALwEkaiAOEBoaQQAhAgsgAgvJBAEDf0EBIAAsAAciASABQQBKG0EBIAAtAAkbIgEgACwAEyICIAEgAkgbIAEgAC0AFRsiASAALAAfIgIgASACSBsgASAALQAhGyIBIAAsACsiAiABIAJIGyABIAAtAC0bIgEgACwANyICIAEgAkgbIAEgAC0AORsiAcAiAiAALABDIgMgAiADSBsgASAALQBFGyIBwCICIAAsAE8iAyACIANIGyABIAAtAFEbIgHAIgIgACwAWyIDIAIgA0gbIAEgAC0AXRsiAcAiAiAALABnIgMgAiADSBsgASAALQBpGyIBwCICIAAsAHMiAyACIANIGyABIAAtAHUbIgHAIgIgACwAfyIDIAIgA0gbIAEgAC0AgQEbIgHAIgIgACwAiwEiAyACIANIGyABIAAtAI0BGyIBwCICIAAsAJcBIgMgAiADSBsgASAALQCZARsiAcAiAiAALACjASIDIAIgA0gbIAEgAC0ApQEbIgHAIgIgACwArwEiAyACIANIGyABIAAtALEBGyIBwCICIAAsALsBIgMgAiADSBsgASAALQC9ARsiAcAiAiAALADHASIDIAIgA0gbIAEgAC0AyQEbIgHAIgIgACwA0wEiAyACIANIGyABIAAtANUBGyIBwCICIAAsAN8BIgMgAiADSBsgASAALQDhARsiAcAiAiAALADrASIDIAIgA0gbIAEgAC0A7QEbIgHAIgIgACwA9wEiAyACIANIGyABIAAtAPkBGyIBwCICIAAsAIMCIgMgAiADSBsgASAALQCFAhvAC8YGAgl/Bn0CQCACKAIAIghBAnQgAE4NACACQQE2AgQgAiAAQQJ1Igg2AgAgAEEMSA0AIANCgICA/AM3AgBBAiEEIAMgCEEBdiIGQQJ0aiIFIAayRBgtRFT7Iek/IAa3o7YiDZQQKSIOOAIEIAUgDjgCACAAQRhJDQADQCADIARBAnQiBWogDSAEspQiDhApIg84AgAgAyAFQQRyaiAOEC8iDjgCACADIAggBGtBAnRqIgUgDzgCBCAFIA44AgAgBEECaiIEIAZJDQALIAggAkEIaiADEFMLAkAgAigCBCIGQQJ0IABODQAgAiAAQQJ1IgY2AgQgAEEISA0AQQEhBCADIAhBAnRqIgUgBkEBdiIHskQYLURU+yHpPyAHt6O2Ig2UECkiDjgCACAFIAdBAnRqIA5DAAAAP5Q4AgAgAEEQSQ0AQQIgByAHQQJNG0EBayIHQQFxIQwgAEEYTwRAIAdBfnEhC0EAIQcDQCAFIARBAnRqIA0gBLKUIg4QKUMAAAA/lDgCACAFIAYgBGtBAnRqIA4QL0MAAAA/lDgCACAFIARBAWoiCUECdGogDSAJspQiDhApQwAAAD+UOAIAIAUgBiAJa0ECdGogDhAvQwAAAD+UOAIAIARBAmohBCAHQQJqIgcgC0cNAAsLIAxFDQAgBSAEQQJ0aiANIASylCINEClDAAAAP5Q4AgAgBSAGIARrQQJ0aiANEC9DAAAAP5Q4AgALAkAgAEEFTgRAIAAgAkEIaiABEFMgACABIAMQUiAGQQF0IABBAXYiB20hCSAAQQVGDQFBAiEEIAMgCEECdGohBUEAIQIDQCABIARBAnQiCGoiAyADKgIAIg1DAAAAPyAFIAYgAiAJaiICa0ECdGoqAgCTIg4gDSABIAAgBGtBAnRqIgMqAgCTIg2UIAEgCEEEcmoiCCoCACIPIAMqAgSSIhAgBSACQQJ0aioCACIRlJMiEpM4AgAgCCAPIA4gEJQgESANlJIiDZM4AgAgAyADKgIAIBKSOAIAIAMgAyoCBCANkzgCBCAEQQJqIgQgB0kNAAsMAQsgAEEERw0AQQQgASADEFILIAEgASoCACINIAEqAgQiDpM4AgQgASANIA6SOAIAC34AQYDYAEEfNgIAQYTYAEEANgIAEFpBhNgAQeTgACgCADYCAEHk4ABBgNgANgIAQbDaAEGQzAAoAgA2AgBB6OAAQSA2AgBB7OAAQQA2AgAQS0Hs4ABB5OAAKAIANgIAQeTgAEHo4AA2AgBBlOIAQZzhADYCAEHM4QBBKjYCAAuaAQAgAEEBOgA1AkAgACgCBCACRw0AIABBAToANAJAIAAoAhAiAkUEQCAAQQE2AiQgACADNgIYIAAgATYCECADQQFHDQIgACgCMEEBRg0BDAILIAEgAkYEQCAAKAIYIgJBAkYEQCAAIAM2AhggAyECCyAAKAIwQQFHDQIgAkEBRg0BDAILIAAgACgCJEEBajYCJAsgAEEBOgA2CwtdAQF/IAAoAhAiA0UEQCAAQQE2AiQgACACNgIYIAAgATYCEA8LAkAgASADRgRAIAAoAhhBAkcNASAAIAI2AhgPCyAAQQE6ADYgAEECNgIYIAAgACgCJEEBajYCJAsLugIBA38jAEFAaiICJAAgACgCACIDQQRrKAIAIQQgA0EIaygCACEDIAJCADcCICACQgA3AiggAkIANwIwIAJCADcANyACQgA3AhggAkEANgIUIAJBpNAANgIQIAIgADYCDCACIAE2AgggACADaiEAQQAhAwJAIAQgAUEAECEEQCACQQE2AjggBCACQQhqIAAgAEEBQQAgBCgCACgCFBEJACAAQQAgAigCIEEBRhshAwwBCyAEIAJBCGogAEEBQQAgBCgCACgCGBEHAAJAAkAgAigCLA4CAAECCyACKAIcQQAgAigCKEEBRhtBACACKAIkQQFGG0EAIAIoAjBBAUYbIQMMAQsgAigCIEEBRwRAIAIoAjANASACKAIkQQFHDQEgAigCKEEBRw0BCyACKAIYIQMLIAJBQGskACADCwoAIAAgAUEAECELmQIAIABFBEBBAA8LAn8CQCAABH8gAUH/AE0NAQJAQZTiACgCACgCAEUEQCABQYB/cUGAvwNGDQMMAQsgAUH/D00EQCAAIAFBP3FBgAFyOgABIAAgAUEGdkHAAXI6AABBAgwECyABQYBAcUGAwANHIAFBgLADT3FFBEAgACABQT9xQYABcjoAAiAAIAFBDHZB4AFyOgAAIAAgAUEGdkE/cUGAAXI6AAFBAwwECyABQYCABGtB//8/TQRAIAAgAUE/cUGAAXI6AAMgACABQRJ2QfABcjoAACAAIAFBBnZBP3FBgAFyOgACIAAgAUEMdkE/cUGAAXI6AAFBBAwECwtB+OAAQRk2AgBBfwVBAQsMAQsgACABOgAAQQELC7QCAAJAAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4SAAgJCggJAQIDBAoJCgoICQUGBwsgAiACKAIAIgFBBGo2AgAgACABKAIANgIADwsgAiACKAIAIgFBBGo2AgAgACABMgEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMwEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMAAANwMADwsgAiACKAIAIgFBBGo2AgAgACABMQAANwMADwsgAiAC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ACwAHyICIAEgAkobIAEgAC0AIRsiASAALAArIgIgASACShsgASAALQAtGyIBIAAsADciAiABIAJKGyABIAAtADkbIgEgACwAQyICIAEgAkobIAEgAC0ARRsiASAALABPIgIgASACShsgASAALQBRGyIBIAAsAFsiAiABIAJKGyABIAAtAF0bIgEgACwAZyICIAEgAkobIAEgAC0AaRsiASAALABzIgIgASACShsgASAALQB1GyIBIAAsAH8iAiABIAJKGyABIAAtAIEBGyIBIAAsAIsBIgIgASACShsgASAALQCNARsiASAALACXASICIAEgAkobIAEgAC0AmQEbIgEgACwAowEiAiABIAJKGyABIAAtAKUBGyIBIAAsAK8BIgIgASACShsgASAALQCxARsiASAALAC7ASICIAEgAkobIAEgAC0AvQEbIgEgACwAxwEiAiABIAJKGyABIAAtAMkBGyIBIAAsANMBIgIgASACShsgASAALQDVARsiASAALADfASICIAEgAkobIAEgAC0A4QEbIgEgACwA6wEiAiABIAJKGyABIAAtAO0BGyIBIAAsAPcBIgIgASACShsgASAALQD5ARsiASAALACDAiICIAEgAkobIAEgAC0AhQIbC9ceAgl/A3wjAEEgayIHJAACf0ECIAAoAkhBjAEgAC0ARBsiBkEESA0AGkEEIAZBD0kNABogBkEFbkEBdAshA0HU3gAtAABFBEBBzNwAECRBiAIQGhpB1N4AQQE6AAALQczcABA1IAMgBmoiCGpBAWshC0HI3AAtAABFBEBBwNoAECRBiAIQGhpByNwAQQE6AAALIAtBwNoAEDVtIQkCQCAIQYECTgRAQbDaACgCACIARQ0BIAdBgAI2AgwgBwJ/QQIgBkEESA0AGkEEIAZBD0kNABogBkEFbkEBdAs2AgggByAGNgIEIAcgCDYCACAAQe4kIAcQHAwBCyAAKAI8IAhqIQMgAQRAIAIoAgAhBCAAIAM2AlggACABIARqNgJUCyACIAMgAigCAGpBB2pBCG1BA3QiBDYCACAALQBMBEAgAiAAKAIMIgNBA3QgAQR/IAAgA0EBdDYCmAEgACABIARqNgKUASACKAIABSAEC2pBB2pBCG1BA3QiAzYCAAJ/IAAoAgxBAm23n0QAAAAAAAAIQKAiDJlEAAAAAAAA4EFjBEAg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OSABIAM6ADogASALQQF0IhM7ATAgASATIANB/gFxIgRqIhM7ATwgASAKOgAMIAEgAjYCBCABIAI2AgggAUEAOwEUIAFBgAI7ASAgAUGABDsBLCABIAFBEGoiAjYCHCABIAI2AiggASACNgI0IAEgBCATaiIKOwFIIAEgAzoARiABIAY6AFIgASADOgBeIAEgAzoAaiABQQg6AHUgASAEIApqIgY7AVQgASAGIAtqIgY7AWAgASAEIAZqIgY7AWwgASAEIAZqIgY7AXggAUGACDsBRCABIAI2AkAgAUEAOgA4IAEgAjYCTCABQYAKOwFQIAEgAjYCWCABQYAMOwFcIAEgAjYCZCABQYAOOwFoIAEgAjYCcCABIAM6AHYgASAEIAZqIgY7AYQBIAEgAzoAggEgASADOgCOASABIAM6AJoBIAFBDDoApQEgASADOgCmASABIAQgBmoiBjsBkAEgASAEIAZqIgY7AZwBIAEgBCAGaiIGOwGoASABQQA6AHQgASACNgJ8IAFBgBI7AYABIAEgAjYCiAEgAUGAFDsBjAEgASACNgKUASABQYAWOwGYASABIAI2AqABIAEgBCAGaiIGOwG0ASABQQ06ALEBIAEgAjYCrAEgAUEAOgCkASABIAM6ALIBIAEgBCAGaiIGOwHAASABQQ46AL0BIAEgAjYCuAEgAUEAOgCwASABIAM6AL4BIAEgBCAGaiIGOwHMASABQQ86AMkBIAEgAjYCxAEgAUEAOgC8ASABIAM6AMoBIAEgBCAGajsB2AEgAUEQOgDVASABIAI2AtABIAFBADoAyAEgASADOgDWASABIAI2AtwBIAFBADoA1AEgASAHKALsBCICIAcoAlQgAiABLQAAEBogAS0AAGoQTgJAIAEtAAxFDQAgASgCBCICRQ0AIAIQIAsgBy0AvAQhAgsgBygCZCEGIAFBADYC3AEgAUEAOgDUASABQQA2AtABIAFBADoAyAEgAUEANgLEASABQQA6ALwBIAFBADYCuAEgAUEAOgCwASABQQA2AqwBIAFBADoApAEgAUEANgKgASABQQA6AJgBIAFBADYClAEgAUEAOgCMASABQQA2AogBIAFBADoAgAEgAUEANgJ8IAFBADoAdCABQQA2AnAgAUEAOgBoIAFBADYCZCABQQA6AFwgAUEANgJYIAFBADoAUCABQQA2Akwg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AkYNABogAiAEKAIEawshCiADQSBqJAAgCgsJACAAKAI8EBULDwAgASAAKAIAaiACOAIACw0AIAEgACgCAGoqAgALJAEBf0Hk4AAoAgAiAARAA0AgACgCABEEACAAKAIEIgANAAsLCyQBAn8gACgCBCIAEEJBAWoiARAlIgIEfyACIAAgARAaBUEACwttAQN/IwBBEGsiAiQAAkACQCAAQQNLDQAgAEECdEGg2gBqIgMoAgAiAUUNACABKALwByIABEAgABAgCyABECAgA0EANgIADAELQbDaACgCACIBRQ0AIAIgADYCACABQfIeIAIQHAsgAkEQaiQAC6QTAwp/An0BfiMAQTBrIgQkAAJAAkBBoNoAKAIARQRAQaDaACEHDAELQaTaACgCAEUEQEGk2gAhB0EBIQgMAQtBqNoAKAIARQRAQajaACEHQQIhCAwBC0Gs2gAoAgBFBEBBrNoAIQdBAyEIDAELQX8hCEGw2gAoAgAiAEUNASAEQQQ2AgAgAEGjIyAEEBwMAQtB+AcQHSEBIAQgACgCADYCDCAEIAAqAgQ4AhAgBCAAKgIIOAIUIAQgACoCDDgCGCAEIAAoAhA2AhwgBCAAKgIUOAIgIAQgACgCGDYCJCAEIAAoAhw2AiggBCAAKAIgNgIsIAFBfzYCSCABQQA6AEQgAUGAgID8ezYCQCABQn83AzggAUKAgID8ezcDMCABQoCAgPx7NwMoIAFCgICAgICAgMC/fzcDICABQv////8PNwMYIAFCgICA/Hs3AxAgAUKAgID8ezcDCCABQoCAgPyLgIDAv383AwAgAUIANwNwIAFCADcDeCABQgA3A4ABIAFCADcDiAEgAUIANwOQASABQgA3A5gBIAFCADcDoAEgAUIANwCnASABQQA2AtgBIAFCADcD0AEgAUIANwPIASABQgA3A8ABIAFCADcDuAEgAUIANwOwASABQQA2AkwgAUEAOgBQIAFCADcCVCABQgA3AlwgAUIANwJkIAFBADsBbCABQfQDakEAQcEAEBsaIAFCADcCvAQgAUHNmbPuAzYCuAQgAUIANwLEBCABQgA3AswEIAFCADcC1AQgAUIANwLcBCABQgA3AuQEIAFCADcC7AQgAUIANwOIByABQgA3A5AHIAFCADcDmAcgAUIANwKgByABQQA2ArAHIAFCADcDqAcgAUIANwO4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AWoiAjYCeEGw2gAoAgAiBwRAIAMgAjYCBCADIAA2AgAgB0GyHyADEBwLIARBATYChAEgBEEANgJwDAELIARBADYCcAsgA0GgAmokAAsCQCAQIAQoAgwiBmsiC0EATA0AIAQoArgBIQhBACECQQAhACAQIAZBf3NqQQNPBEAgC0F8cSEFQQAhBwNAIAggAEECdGogCCAAIAZqQQJ0aioCADgCACAIIABBAXIiA0ECdGogCCADIAZqQQJ0aioCADgCACAIIABBAnIiA0ECdGogCCADIAZqQQJ0aioCADgCACAIIABBA3IiA0ECdGogCCADIAZqQQJ0aioCADgCACAAQQRqIQAgB0EEaiIHIAVHDQALCyALQQNxIgdFDQADQCAIIABBAnRqIAggACAGakECdGoqAgA4AgAgAEEBaiEAIAJBAWoiAiAHRw0ACwsgGyAYayEbIBggGmohGiAEIAYgC2siADYCkAEMAQsLIAQgBiAQazYCkAELIBxBEGokAAJAIANFBEBBfyEAQbDaACgCACICRQ0BIB4gATYCACACQcYeIB4QHAwBC0EAIQBBvNoALQAARQRAQbzaAEEBOgAAQbTaAEIANwIACyAEKALQASIBRQ0AIARBADYC0AFBfyEAIAFBf0YNACAEKALUASEAQbjaACABNgIAQbTaACAANgIAIAFBAEoEQEGg2AAgACABEBoaCyABIQALIB5BEGokACAAQQBKBEAgF0Gg2AA2AgwgFyAANgIIQdAoIBdBCGoQBwwBCyAXQaDYADYCDCAXQQA2AghB0CggF0EIahAHCzYCACAXQRBqJAALsAEBBH8jAEEQayIDJAAgAigCACIEQfD///8HSQRAAkAgBEEKTQRAIAMgBDoACyADIQUMAQsgBEEPckEBaiIGEB0hBSADIAZBgICAgHhyNgIIIAMgBTYCACADIAQ2AgQLIAUgAkEEaiAEEBogBGpBADoAACADQQxqIAEgAyAAEQEAIAMoAgwQCSADKAIMIgAQCCADLAALQQBIBEAgAygCABAgCyADQRBqJAAgAA8LEFYAC6MFAQt/IwBBEGsiCiQAIAEgAigCACACIAItAAsiB8BBAEgiBRsgAigCBCAHIAUbIAMgBEEAQQEQUSEFAkBBlNgALQAARQRAQYjYAEIANwIAQZDYAEEANgIAIAUEQCAFQQBIDQJBiNgAIAUQHSIHNgIAQZDYACAFIAdqIgY2AgAgB0EAIAUQGxpBjNgAIAY2AgALQZTYAEEBOgAACwJAQYzYACgCACIGQYjYACgCACIHayIIIAVJBEBBACEHAkAgBSAIayIJQZDYACgCACIIIAZrTQRAQYzYACAJBH8gBkEAIAkQGyAJagUgBgs2AgAMAQsgBkGI2AAoAgAiC2siDCAJaiIFQQBOBEBB/////wcgCCALayIIQQF0Ig0gBSAFIA1JGyAIQf////8DTxsiBQRAIAUQHSEHCyAFIAdqIQ0gCSAHIAxqIghBACAJEBsiBWohCQJAIAYgC0YEQCAFIQcMAQsgC0F/cyAGaiEPIAxBA3EiDARAQQAhBQNAIAhBAWsiCCAGQQFrIgYtAAA6AAAgBUEBaiIFIAxHDQALCyAPQQNPBEADQCAIQQFrIAZBAWstAAA6AAAgCEECayAGQQJrLQAAOgAAIAhBA2sgBkEDay0AADoAACAIQQRrIgggBkEEayIGLQAAOgAAIAYgC0cNAAsLQYjYACgCACEGC0GQ2AAgDTYCAEGM2AAgCTYCAEGI2AAgBzYCACAGBEAgBhAgCwwBCxBUAAtBiNgAKAIAIQcMAQsgBSAITw0AQYzYACAFIAdqNgIACyABIAIoAgAgAiACLQALIgHAQQBIIgUbIAIoAgQgASAFGyADIAQgB0EAEFEhASAKQYjYACgCADYCDCAKIAE2AgggAEHQKCAKQQhqEAc2AgAgCkEQaiQADwsQVAALIgEBfiABIAKtIAOtQiCGhCAEIAAREwAiBUIgiKckASAFpwu0AQEEfyMAQRBrIgUkACACKAIAIgZB8P///wdJBEACQCAGQQpNBEAgBSAGOgALIAUhBwwBCyAGQQ9yQQFqIggQHSEHIAUgCEGAgICAeHI2AgggBSAHNgIAIAUgBjYCBAsgByACQQRqIAYQGiAGakEAOgAAIAVBDGogASAFIAMgBCAAEQcAIAUoAgwQCSAFKAIMIgAQCCAFLAALQQBIBEAgBSgCABAgCyAFQRBqJAAgAA8LEFYACwcAIAAoAgQLBQBBwgoLFgAgAEUEQEEADwsgAEG00QAQOkEARwsaACAAIAEoAgggBRAhBEAgASACIAMgBBA4Cws3ACAAIAEoAgggBRAhBEAgASACIAMgBBA4DwsgACgCCCIAIAEgAiADIAQgBSAAKAIAKAIUEQkAC6cBACAAIAEoAgggBBAhBEACQCABKAIEIAJHDQAgASgCHEEBRg0AIAEgAzYCHAsPCwJAIAAgASgCACAEECFFDQACQCACIAEoAhBHBEAgASgCFCACRw0BCyADQQFHDQEgAUEBNgIgDwsgASACNgIUIAEgAzYCICABIAEoAihBAWo2AigCQCABKAIkQQFHDQAgASgCGEECRw0AIAFBAToANgsgAUEENgIsCwsJACABIAARAgALC4VOFwBBgAgLpx8tKyAgIDBYMHgALTBYKzBYIDBYLTB4KzB4IDB4AHNhbXBsZUZvcm1hdE91dABzYW1wbGVSYXRlT3V0AFtVXSBGYXN0ZXN0AFtNVF0gRmFzdGVzdABbRFRdIEZhc3Rlc3QAW1VdIEZhc3QAW01UXSBGYXN0AFtEVF0gRmFzdAB1bnNpZ25lZCBzaG9ydAB0eFByb3RvY29sU2V0RnJlcVN0YXJ0AHJ4UHJvdG9jb2xTZXRGcmVxU3RhcnQAdW5zaWduZWQgaW50AGluaXQAZmxvYXQAU2FtcGxlRm9ybWF0AHVpbnQ2NF90AGdldERlZmF1bHRQYXJhbWV0ZXJzAHJ4RHVyYXRpb25GcmFtZXMAdmVjdG9yAHVuc2lnbmVkIGNoYXIAc2FtcGxlRm9ybWF0SW5wAHNhbXBsZVJhdGVJbnAAc3RkOjpleGNlcHRpb24AbmFuAGJvb2wAdHhUb2dnbGVQcm90b2NvbAByeFRvZ2dsZVByb3RvY29sAGVtc2NyaXB0ZW46OnZhbABbVV0gTm9ybWFsAFtNVF0gTm9ybWFsAFtEVF0gTm9ybWFsAHBheWxvYWRMZW5ndGgAZGlzYWJsZUxvZwBlbmFibGVMb2cAdW5zaWduZWQgbG9uZwBzdGQ6OndzdHJpbmcAYmFzaWNfc3RyaW5nAHN0ZDo6c3RyaW5nAHN0ZDo6dTE2c3RyaW5nAHN0ZDo6dTMyc3RyaW5nAGluZgBzYW1wbGVSYXRlAHNhbXBsZXNQZXJGcmFtZQBkb3VibGUAZnJlZQBlbmNvZGUAZGVjb2RlAG9wZXJhdGluZ01vZGUAc291bmRNYXJrZXJUaHJlc2hvbGQAdm9pZABQcm90b2NvbElkAEdHV0FWRV9PUEVSQVRJTkdfTU9ERV9UWABHR1dBVkVfT1BFUkFUSU5HX01PREVfUlhfQU5EX1RYAEdHV0FWRV9PUEVSQVRJTkdfTU9ERV9SWABHR1dBVkVfUFJPVE9DT0xfTVRfRkFTVEVTVABHR1dBVkVfUFJPVE9DT0xfRFRfRkFTVEVTVABHR1dBVkVfUFJPVE9DT0xfQVVESUJMRV9GQVNURVNUAEdHV0FWRV9QUk9UT0NPTF9VTFRSQVNPVU5EX0ZBU1RFU1QAR0dXQVZFX1BST1RPQ09MX01UX0ZBU1QAR0dXQVZFX1BST1RPQ09MX0RUX0ZBU1QAR0dXQVZFX1BST1RPQ09MX0FVRElCTEVfRkFTVABHR1dBVkVfUFJPVE9DT0xfVUxUUkFTT1VORF9GQVNUAEdHV0FWRV9PUEVSQVRJTkdfTU9ERV9VU0VfRFNTAEdHV0FWRV9PUEVSQVRJTkdfTU9ERV9UWF9PTkxZX1RPTkVTAE5BTgBHR1dBVkVfUFJPVE9DT0xfTVRfTk9STUFMAEdHV0FWRV9QUk9UT0NPTF9EVF9OT1JNQUwAR0dXQVZFX1BST1RPQ09MX0FVRElCTEVfTk9STUFMAEdHV0FWRV9QUk9UT0NPTF9VTFRSQVNPVU5EX05PUk1BTABJTkYAR0dXQVZFX1NBTVBMRV9GT1JNQVRfVU5ERUZJTkVEAGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHNob3J0PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBpbnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGZsb2F0PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQ4X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQxNl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQxNl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50NjRfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50NjRfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGNoYXI+AHN0ZDo6YmFzaWNfc3RyaW5nPHVuc2lnbmVkIGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxsb25nPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBsb25nPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxkb3VibGU+AEdHV0FWRV9QUk9UT0NPTF9DVVNUT01fOQBHR1dBVkVfUFJPVE9DT0xfQ1VTVE9NXzgAR0dXQVZFX1NBTVBMRV9GT1JNQVRfVTgAR0dXQVZFX1NBTVBMRV9GT1JNQVRfSTgAR0dXQVZFX1BST1RPQ09MX0NVU1RPTV83AEdHV0FWRV9QUk9UT0NPTF9DVVNUT01fNgBHR1dBVkVfU0FNUExFX0ZPUk1BVF9VMTYAR0dXQVZFX1NBTVBMRV9GT1JNQVRfSTE2AEdHV0FWRV9QUk9UT0NPTF9DVVNUT01fNQBHR1dBVkVfUFJPVE9DT0xfQ1VTVE9NXzQAR0dXQVZFX1BST1RPQ09MX0NVU1RPTV8zAEdHV0FWRV9QUk9UT0NPTF9DVVNUT01fMgBHR1dBVkVfU0FNUExFX0ZPUk1BVF9GMzIAR0dXQVZFX1BST1RPQ09MX0NVU1RPTV8xAEdHV0FWRV9QUk9UT0NPTF9DVVNUT01fMAAuAChudWxsKQBFcnJvcjogY2FwdHVyZSBzYW1wbGUgcmF0ZSAoJWcgSHopIG11c3QgYmUgPj0gJWcgSHoKAEVycm9yOiBjYXB0dXJlIHNhbXBsZSByYXRlICglZyBIeikgbXVzdCBiZSA8PSAlZyBIegoARXJyb3I6IGZhaWxlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIHRoZSByZXF1aXJlZCBtZW1vcnkKAFRydW5jYXRpbmcgZGF0YSBmcm9tICVkIHRvICVkIGJ5dGVzCgBDYW5ub3QgZGVjb2RlIHdoaWxlIHRyYW5zbWl0dGluZwoAVHggaXMgZGlzYWJsZWQgLSBjYW5ub3QgdHJhbnNtaXQgZGF0YSB3aXRoIHRoaXMgR0dXYXZlIGluc3RhbmNlCgBSeCBpcyBkaXNhYmxlZCAtIGNhbm5vdCByZWNlaXZlIGRhdGEgd2l0aCB0aGlzIEdHV2F2ZSBpbnN0YW5jZQoAUHJvdG9jb2wgJWQgaXMgbm90IGVuYWJsZWQgLSBtYWtlIHN1cmUgdG8gZW5hYmxlIGl0IGJlZm9yZSBjcmVhdGluZyB0aGUgaW5zdGFuY2UKAE1vbm8tdG9uZSBwcm90b2NvbHMgd2l0aCB2YXJpYWJsZSBsZW5ndGggYXJlIG5vdCBzdXBwb3J0ZWQKAEZhaWxlZCB0byBpbml0aWFsaXplIFR4IHRyYW5zbWlzc2lvbiBmb3IgR0dXYXZlIGluc3RhbmNlICVkCgBJbnZhbGlkIEdHV2F2ZSBpbnN0YW5jZSAlZAoARmFpbGVkIHRvIGVuY29kZSBkYXRhIC0gR0dXYXZlIGluc3RhbmNlICVkCgBGYWlsZWQgdG8gZGVjb2RlIGRhdGEgLSBHR1dhdmUgaW5zdGFuY2UgJWQKAEZhaWxlZCB0byBmcmVlIEdHV2F2ZSBpbnN0YW5jZSAtIGludmFsaWQgR0dXYXZlIGluc3RhbmNlIGlkICVkCgBSZWNlaXZlZCBlbmQgbWFya2VyLiBGcmFtZXMgbGVmdCA9ICVkLCByZWNvcmRlZCA9ICVkCgBFcnJvcjogZmFpbGVkIHRvIGFsbG9jYXRlIHRoZSByZXF1aXJlZCBtZW1vcnk6ICVkCgBJbnZhbGlkIHBheWxvYWQgbGVuZ3RoOiAlZCwgbWF4OiAlZAoASW52YWxpZCBzYW1wbGVzIHBlciBmcmFtZTogJWQsIG1heDogJWQKAEludmFsaWQgb3IgdW5zdXBwb3J0ZWQgcGxheWJhY2sgc2FtcGxlIGZvcm1hdDogJWQKAEludmFsaWQgb3IgdW5zdXBwb3J0ZWQgY2FwdHVyZSBzYW1wbGUgZm9ybWF0OiAlZAoASW52YWxpZCBzYW1wbGUgZm9ybWF0OiAlZAoATmVnYXRpdmUgZGF0YSBzaXplOiAlZAoARXJyb3I6IGZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnkgLSBoZWFwU2l6ZTA6ICVkLCBoZWFwU2l6ZTogJWQKAEludmFsaWQgdm9sdW1lOiAlZAoASW52YWxpZCBwcm90b2NvbCBJRDogJWQKAFJlY2VpdmluZyBzb3VuZCBkYXRhIC4uLgoAQW5hbHl6aW5nIGNhcHR1cmVkIGRhdGEgLi4KAEZhaWxlZCB0byBjcmVhdGUgR0dXYXZlIGluc3RhbmNlIC0gcmVhY2hlZCBtYXhpbXVtIG51bWJlciBvZiBpbnN0YW5jZXMgKCVkKQoARmFpbHVyZSBkdXJpbmcgY2FwdHVyZSAtIHByb3ZpZGVkIGJ5dGVzICglZCkgYXJlIG5vdCBtdWx0aXBsZSBvZiBzYW1wbGUgc2l6ZSAoJWQpCgBEZWNvZGVkIGxlbmd0aCA9ICVkLCBwcm90b2NvbCA9ICclcycgKCVkKQoARXJyb3I6IHRvdGFsIGxlbmd0aCAlZCAocGF5bG9hZCAlZCArIEVDQyAlZCBieXRlcykgaXMgdG9vIGxhcmdlICggPiAlZCkKAEZhaWxlZCB0byBjYXB0dXJlIHNvdW5kIGRhdGEuIFBsZWFzZSB0cnkgYWdhaW4gKGxlbmd0aCA9ICVkKQoAUmVjZWl2ZWQgc291bmQgZGF0YSBzdWNjZXNzZnVsbHk6ICclcycKADE5Z2d3YXZlX1NhbXBsZUZvcm1hdAAAzCkAAB0TAAAxN2dnd2F2ZV9Qcm90b2NvbElkAMwpAAA8EwAAMTdnZ3dhdmVfUGFyYW1ldGVycwAYKgAAWBMAAGkAdmkAaWlpAHZpaWkAZmlpAHZpaWYAAGwTAABpaQAAaCkAAGwTAAAUKQAAaCkAAHZpaQBBsCcL0gHYEwAAaCkAACAUAABQEwAAaCkAAE4xMGVtc2NyaXB0ZW4zdmFsRQAAGCoAAMQTAABOU3QzX18yMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFRQAAGCoAAOATAABpaWlpaWkATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJY0VFAAAAGCoAAC8UAADYEwAAaCkAACAUAABpaWlpAAAAABQpAAAUKQAAUBMAAGgpAABoKQAAaCkAQZApC7cilp+0rxuR3sVFdeguDzJKX7RWlct/alRqSPILe837k208d17DM0fA8XEyMyc1aEcfTqwjQl8AN6RQbUgkkXyhTgAAARkCMhrGA98z7htox0sEZOAONI3vgRzBafjICExxBYplL+EkDyE1k47a8BKCRR21wn1qJ/m5yZoJeE3kcqYGv4tiZt0w/eKYJbMQkSKINtCUzo+W273x0hNcgzhGQB5CtqPDSH5uazooVPqFuj3KXpufChV5K07U5axz86dXB3DA94yAYw1nSt7tMcX+GOOlmXcmuLR8EUSS2SMgiS43P9FblbzPzZCHl7Lc/L5h8lbTqxQqXZ6EPDlTR21Boh8tQ9i3e6R2xBdJ7H8Mb/ZsoTtSKZ1VqvtghrG7zD5ay1lfsJypoFEL9RbrenUs10+u1enm563odNb06qhQWK8BAgQIECBAgB06dOjNhxMmTJgtWrR16smPAwYMGDBgwJ0nTpwlSpQ1atS1d+7BnyNGjAUKFChQoF26adK5b96hX75hwpkvXrxlyokPHjx48P3n07tr1rF//uHfo1u2ceLZr0OGESJEiA0aNGjQvWfOgR8+fPjtx5M7duzFlzNmzIUXLly4bdqpT54hQoQVKlSoTZopUqRVqkmSOXLk1bdz5tG/Y8aRP3785deze/bx/+Pbq0uWMWLElTdu3KVXrkGCGTJkyI0HDhw4cODdp1OmUaJZsnny+e/DmytWrEWKCRIkSJA9evT19/P768uLCxYsWLB9+unPgxs2bNitR44BAgQIECBAgB06dOjNhxMmTJgtWrR16smPAwYMGDBgwJ0nTpwlSpQ1atS1d+7BnyNGjAUKFChQoF26adK5b96hX75hwpkvXrxlyokPHjx48P3n07tr1rF//uHfo1u2ceLZr0OGESJEiA0aNGjQvWfOgR8+fPjtx5M7duzFlzNmzIUXLly4bdqpT54hQoQVKlSoTZopUqRVqkmSOXLk1bdz5tG/Y8aRP3785deze/bx/+Pbq0uWMWLElTdu3KVXrkGCGTJkyI0HDhw4cODdp1OmUaJZsnny+e/DmytWrEWKCRIkSJA9evT19/P768uLCxYsWLB9+unPgxs2bNitR44BAgAAAAABAAAAAQAAAAIAAAACAAAABAAAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0loTlNfMTFjaGFyX3RyYWl0c0loRUVOU185YWxsb2NhdG9ySWhFRUVFAAAYKgAA6BcAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0l3TlNfMTFjaGFyX3RyYWl0c0l3RUVOU185YWxsb2NhdG9ySXdFRUVFAAAYKgAAMBgAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEc05TXzExY2hhcl90cmFpdHNJRHNFRU5TXzlhbGxvY2F0b3JJRHNFRUVFAAAAGCoAAHgYAABOU3QzX18yMTJiYXNpY19zdHJpbmdJRGlOU18xMWNoYXJfdHJhaXRzSURpRUVOU185YWxsb2NhdG9ySURpRUVFRQAAABgqAADEGAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJYUVFAAAYKgAAEBkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWhFRQAAGCoAADgZAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lzRUUAABgqAABgGQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJdEVFAAAYKgAAiBkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWlFRQAAGCoAALAZAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lqRUUAABgqAADYGQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJbEVFAAAYKgAAABoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SW1FRQAAGCoAACgaAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l4RUUAABgqAABQGgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJeUVFAAAYKgAAeBoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWZFRQAAGCoAAKAaAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lkRUUAABgqAADIGgAAAwAAAAQAAAAEAAAABgAAAIP5ogBETm4A/CkVANFXJwDdNPUAYtvAADyZlQBBkEMAY1H+ALveqwC3YcUAOm4kANJNQgBJBuAACeouAByS0QDrHf4AKbEcAOg+pwD1NYIARLsuAJzphAC0JnAAQX5fANaROQBTgzkAnPQ5AItfhAAo+b0A+B87AN7/lwAPmAUAES/vAApaiwBtH20Az342AAnLJwBGT7cAnmY/AC3qXwC6J3UA5evHAD178QD3OQcAklKKAPtr6gAfsV8ACF2NADADVgB7/EYA8KtrACC8zwA29JoA46kdAF5hkQAI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";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}var binary=tryParseAsDataURI(file);if(binary){return binary}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(instance=>instance).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"a":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;wasmExports=exports;wasmMemory=wasmExports["A"];updateMemoryViews();wasmTable=wasmExports["C"];addOnInit(wasmExports["B"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;this.set_type=function(type){HEAPU32[this.ptr+4>>2]=type};this.get_type=function(){return HEAPU32[this.ptr+4>>2]};this.set_destructor=function(destructor){HEAPU32[this.ptr+8>>2]=destructor};this.get_destructor=function(){return HEAPU32[this.ptr+8>>2]};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)};this.set_adjusted_ptr=function(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr};this.get_adjusted_ptr=function(){return HEAPU32[this.ptr+16>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var structRegistrations={};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAP32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError=undefined;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i<myTypes.length;++i){registerType(myTypes[i],myTypeConverters[i])}}var typeConverters=new Array(dependentTypes.length);var unregisteredTypes=[];var registered=0;dependentTypes.forEach((dt,i)=>{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};var __embind_finalize_value_object=structType=>{var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};fieldRecords.forEach((field,i)=>{var fieldName=field.fieldName;var getterReturnType=fieldTypes[i];var getter=field.getter;var getterContext=field.getterContext;var setterArgumentType=fieldTypes[i+fieldRecords.length];var setter=field.setter;var setterContext=field.setterContext;fields[fieldName]={read:ptr=>getterReturnType["fromWireType"](getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,o));runDestructors(destructors)}}});return[{name:reg.name,"fromWireType":ptr=>{var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},"toWireType":(destructors,o)=>{for(var fieldName in fields){if(!(fieldName in o)){throw new TypeError(`Missing field: "${fieldName}"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:rawDestructor}]})};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes=undefined;var readLatin1String=ptr=>{var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret};var BindingError=undefined;var throwBindingError=message=>{throw new BindingError(message)};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":function(pointer){return this["fromWireType"](HEAPU8[pointer])},destructorFunction:null})};var __embind_register_constant=(name,type,value)=>{name=readLatin1String(name);whenDependentTypesAreResolved([],[type],function(type){type=type[0];Module[name]=type["fromWireType"](value);return[]})};function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;var __emval_decref=handle=>{if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}};var count_emval_handles=()=>{var count=0;for(var i=emval_handles.reserved;i<emval_handles.allocated.length;++i){if(emval_handles.allocated[i]!==undefined){++count}}return count};var init_emval=()=>{emval_handles.allocated.push({value:undefined},{value:null},{value:true},{value:false});emval_handles.reserved=emval_handles.allocated.length;Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};var __embind_register_emval=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":(destructors,value)=>Emval.toHandle(value),"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})};var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var enumReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?function(pointer){return this["fromWireType"](HEAP8[pointer>>0])}:function(pointer){return this["fromWireType"](HEAPU8[pointer>>0])};case 2:return signed?function(pointer){return this["fromWireType"](HEAP16[pointer>>1])}:function(pointer){return this["fromWireType"](HEAPU16[pointer>>1])};case 4:return signed?function(pointer){return this["fromWireType"](HEAP32[pointer>>2])}:function(pointer){return this["fromWireType"](HEAPU32[pointer>>2])};default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_enum=(rawType,name,size,isSigned)=>{name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":(destructors,c)=>c.value,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":enumReadValueFromPointer(name,size,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function createNamedFunction(name,body){name=makeLegalFunctionName(name);return{[name]:function(){return body.apply(this,arguments)}}[name]}var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl};var __embind_register_enum_value=(rawEnumType,name,enumValue)=>{var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(`${enumType.name}_${name}`,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":value=>value,"toWireType":(destructors,value)=>value,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":floatReadValueFromPointer(name,size),destructorFunction:null})};function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i<argTypes.length;++i){if(argTypes[i]!==null&&argTypes[i].destructorFunction===undefined){needsDestructorStack=true;break}}var returns=argTypes[0].name!=="void";var argsList="";var argsListWired="";for(var i=0;i<argCount-2;++i){argsList+=(i!==0?", ":"")+"arg"+i;argsListWired+=(i!==0?", ":"")+"arg"+i+"Wired"}var invokerFnBody=`\n        return function ${makeLegalFunctionName(humanName)}(${argsList}) {\n        if (arguments.length !== ${argCount-2}) {\n          throwBindingError('function ${humanName} called with ' + arguments.length + ' arguments, expected ${argCount-2}');\n        }`;if(needsDestructorStack){invokerFnBody+="var destructors = [];\n"}var dtorStack=needsDestructorStack?"destructors":"null";var args1=["throwBindingError","invoker","fn","runDestructors","retType","classParam"];var args2=[throwBindingError,cppInvokerFunc,cppTargetFunc,runDestructors,argTypes[0],argTypes[1]];if(isClassMethodFunc){invokerFnBody+="var thisWired = classParam.toWireType("+dtorStack+", this);\n"}for(var i=0;i<argCount-2;++i){invokerFnBody+="var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";args1.push("argType"+i);args2.push(argTypes[i+2])}if(isClassMethodFunc){argsListWired="thisWired"+(argsListWired.length>0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){var paramName=i===1?"thisWired":"arg"+(i-2)+"Wired";if(argTypes[i].destructorFunction!==null){invokerFnBody+=paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";args1.push(paramName+"_dtor");args2.push(argTypes[i].destructorFunction)}}}if(returns){invokerFnBody+="var ret = retType.fromWireType(rv);\n"+"return ret;\n"}else{}invokerFnBody+="}\n";args1.push(invokerFnBody);return newFunc(Function,args1).apply(null,args2)}var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i<count;i++){array.push(HEAPU32[firstElement+i*4>>2])}return array};var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError=undefined;var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer>>0]:pointer=>HEAPU8[pointer>>0];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<<bitshift>>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})};function readPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":value=>{var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i<length;++i){a[i]=String.fromCharCode(HEAPU8[payload+i])}str=a.join("")}_free(value);return str},"toWireType":(destructors,value)=>{if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var length;var valueIsOfTypeString=typeof value=="string";if(!(valueIsOfTypeString||value instanceof Uint8Array||value instanceof Uint8ClampedArray||value instanceof Int8Array)){throwBindingError("Cannot pass non-string to std::string")}if(stdStringIsUTF8&&valueIsOfTypeString){length=lengthBytesUTF8(value)}else{length=value.length}var base=_malloc(4+length+1);var ptr=base+4;HEAPU32[base>>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i<length;++i){var charCode=value.charCodeAt(i);if(charCode>255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+i]=charCode}}else{for(var i=0;i<length;++i){HEAPU8[ptr+i]=value[i]}}}if(destructors!==null){destructors.push(_free,base)}return base},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":readPointer,destructorFunction:ptr=>_free(ptr)})};var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):undefined;var UTF16ToString=(ptr,maxBytesToRead)=>{var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>HEAPU16;shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>HEAPU32;shift=2}registerType(rawType,{name:name,"fromWireType":value=>{var length=HEAPU32[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:ptr=>_free(ptr)})};var __embind_register_value_object=(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor)=>{structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}};var __embind_register_value_object_field=(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":()=>undefined,"toWireType":(destructors,o)=>undefined})};var __emval_incref=handle=>{if(handle>4){emval_handles.get(handle).refcount+=1}};var __emval_take_value=(type,arg)=>{type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](arg);return Emval.toHandle(v)};var _abort=()=>{abort("")};var _emscripten_memcpy_big=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHe
Download .txt
gitextract_1zhnvrim/

├── .clang-format
├── .github/
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── CMakeLists.txt
├── LICENSE
├── README-tmpl.md
├── README.md
├── bindings/
│   ├── CMakeLists.txt
│   ├── javascript/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── emscripten.cpp
│   │   ├── ggwave.js
│   │   ├── package-tmpl.json
│   │   └── package.json
│   └── python/
│       ├── .gitignore
│       ├── MANIFEST.in
│       ├── Makefile
│       ├── README-tmpl.rst
│       ├── README.md
│       ├── cggwave.pxd
│       ├── debian/
│       │   ├── changelog
│       │   ├── control
│       │   ├── copyright
│       │   ├── python3-ggwave.docs
│       │   ├── rules
│       │   └── source/
│       │       ├── format
│       │       └── options
│       ├── ggwave.pyx
│       ├── setup-tmpl.py
│       ├── setup.py
│       └── test.py
├── cmake/
│   ├── BuildTypes.cmake
│   ├── GitVars.cmake
│   └── sdl2/
│       └── FindSDL2.cmake
├── examples/
│   ├── CMakeLists.txt
│   ├── arduino-rx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-rx.ino
│   │   └── fritzing-sketch.fzz
│   ├── arduino-rx-web/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-rx-web.cpp
│   │   └── index-tmpl.html
│   ├── arduino-tx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── arduino-tx.ino
│   │   └── fritzing-sketch.fzz
│   ├── arduino-tx-obsolete/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── arduino-tx.ino
│   │   └── ggwave.h
│   ├── buttons/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── index-tmpl.html
│   ├── dr_wav.h
│   ├── esp32-rx/
│   │   ├── .gitignore
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── esp32-rx.ino
│   │   └── fritzing-sketch.fzz
│   ├── ggwave-cli/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── main.cpp
│   ├── ggwave-common-sdl2.cpp
│   ├── ggwave-common-sdl2.h
│   ├── ggwave-common.cpp
│   ├── ggwave-common.h
│   ├── ggwave-from-file/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── main.cpp
│   ├── ggwave-js/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   └── index-tmpl.html
│   ├── ggwave-py/
│   │   ├── README.md
│   │   ├── receive.py
│   │   └── send.py
│   ├── ggwave-rx/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── ggwave-to-file/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── ggwave-to-file-local.py
│   │   ├── ggwave-to-file.php
│   │   ├── ggwave-to-file.py
│   │   └── main.cpp
│   ├── ggwave-wasm/
│   │   ├── CMakeLists.txt
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   ├── main.js
│   │   └── style.css
│   ├── icons_font_awesome.h
│   ├── pfd/
│   │   ├── COPYING
│   │   └── pfd.h
│   ├── r2t2/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   ├── main.js
│   │   ├── r2t2-rx.cpp
│   │   └── style.css
│   ├── rp2040-rx/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── fritzing-sketch.fzz
│   │   ├── mic-analog.cpp
│   │   ├── mic-analog.h
│   │   └── rp2040-rx.ino
│   ├── spectrogram/
│   │   ├── CMakeLists.txt
│   │   ├── README.md
│   │   ├── build_timestamp-tmpl.h
│   │   ├── index-tmpl.html
│   │   ├── main.cpp
│   │   └── style.css
│   ├── third-party/
│   │   ├── CMakeLists.txt
│   │   └── imgui/
│   │       ├── CMakeLists.txt
│   │       └── imgui-extra/
│   │           ├── imgui_impl.cpp
│   │           ├── imgui_impl.h
│   │           ├── imgui_impl_opengl3.cpp
│   │           ├── imgui_impl_opengl3.h
│   │           ├── imgui_impl_sdl.cpp
│   │           └── imgui_impl_sdl.h
│   └── waver/
│       ├── CMakeLists.txt
│       ├── README.md
│       ├── build_timestamp-tmpl.h
│       ├── common.cpp
│       ├── common.h
│       ├── index-tmpl.html
│       ├── interface-emscripten.cpp
│       ├── interface-unix.cpp
│       ├── interface.cpp
│       ├── interface.h
│       ├── main.cpp
│       └── style.css
├── include/
│   └── ggwave/
│       └── ggwave.h
├── media/
│   └── favicons-waver/
│       ├── browserconfig.xml
│       └── manifest.json
├── snap/
│   └── snapcraft.yaml
├── src/
│   ├── CMakeLists.txt
│   ├── fft.h
│   ├── ggwave.cpp
│   └── reed-solomon/
│       ├── LICENSE
│       ├── gf.hpp
│       ├── poly.hpp
│       └── rs.hpp
└── tests/
    ├── CMakeLists.txt
    ├── test-ggwave.c
    ├── test-ggwave.cpp
    ├── test-ggwave.js
    └── test-ggwave.py
Download .txt
SYMBOL INDEX (570 symbols across 40 files)

FILE: bindings/javascript/emscripten.cpp
  function EMSCRIPTEN_BINDINGS (line 6) | EMSCRIPTEN_BINDINGS(ggwave) {

FILE: bindings/javascript/ggwave.js
  function locateFile (line 8) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
  function updateMemoryViews (line 8) | function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEA...
  function preRun (line 8) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
  function initRuntime (line 8) | function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__AT...
  function postRun (line 8) | function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="f...
  function addOnPreRun (line 8) | function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}
  function addOnInit (line 8) | function addOnInit(cb){__ATINIT__.unshift(cb)}
  function addOnPostRun (line 8) | function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}
  function addRunDependency (line 8) | function addRunDependency(id){runDependencies++;if(Module["monitorRunDep...
  function removeRunDependency (line 8) | function removeRunDependency(id){runDependencies--;if(Module["monitorRun...
  function abort (line 8) | function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what=...
  function isDataURI (line 8) | function isDataURI(filename){return filename.startsWith(dataURIPrefix)}
  function isFileURI (line 8) | function isFileURI(filename){return filename.startsWith("file://")}
  function getBinarySync (line 8) | function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return...
  function getBinaryPromise (line 8) | function getBinaryPromise(binaryFile){return Promise.resolve().then(()=>...
  function instantiateArrayBuffer (line 8) | function instantiateArrayBuffer(binaryFile,imports,receiver){return getB...
  function instantiateAsync (line 8) | function instantiateAsync(binary,binaryFile,imports,callback){return ins...
  function createWasm (line 8) | function createWasm(){var info={"a":wasmImports};function receiveInstanc...
  function ExceptionInfo (line 8) | function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;thi...
  function simpleReadValueFromPointer (line 8) | function simpleReadValueFromPointer(pointer){return this["fromWireType"]...
  function onComplete (line 8) | function onComplete(typeConverters){var myTypeConverters=getTypeConverte...
  function sharedRegisterType (line 8) | function sharedRegisterType(rawType,registeredInstance,options={}){var n...
  function registerType (line 8) | function registerType(rawType,registeredInstance,options={}){if(!("argPa...
  function handleAllocatorInit (line 8) | function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{...
  function HandleAllocator (line 8) | function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}
  function ctor (line 8) | function ctor(){}
  function createNamedFunction (line 8) | function createNamedFunction(name,body){name=makeLegalFunctionName(name)...
  function newFunc (line 8) | function newFunc(constructor,argumentList){if(!(constructor instanceof F...
  function craftInvokerFunction (line 8) | function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFun...
  function makeDynCaller (line 8) | function makeDynCaller(){if(signature.includes("j")){return getDynCaller...
  function visit (line 8) | function visit(type){if(seen[type]){return}if(registeredTypes[type]){ret...
  function decodeMemoryView (line 8) | function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=H...
  function readPointer (line 8) | function readPointer(pointer){return this["fromWireType"](HEAPU32[pointe...
  method get (line 8) | get(){var ret=HEAP32[SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret}
  method getp (line 8) | getp(){return SYSCALLS.get()}
  method getStr (line 8) | getStr(ptr){var ret=UTF8ToString(ptr);return ret}
  function _fd_seek (line 8) | function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset...
  method constructor (line 8) | constructor(message){super(message);this.name="InternalError"}
  method constructor (line 8) | constructor(message){super(message);this.name="BindingError"}
  function intArrayFromBase64 (line 8) | function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined...
  function tryParseAsDataURI (line 8) | function tryParseAsDataURI(filename){if(!isDataURI(filename)){return}ret...
  function run (line 8) | function run(){if(runDependencies>0){return}preRun();if(runDependencies>...

FILE: examples/arduino-rx-web/arduino-rx-web.cpp
  function mainUpdate (line 39) | void mainUpdate(void *) {
  function EMSCRIPTEN_KEEPALIVE (line 46) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 52) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 58) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 61) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 64) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 67) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 70) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 73) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 76) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 79) | EMSCRIPTEN_KEEPALIVE
  function GGWave_setDefaultCaptureDeviceName (line 83) | void GGWave_setDefaultCaptureDeviceName(std::string name) {
  function GGWave_init (line 87) | bool GGWave_init(
  function GGWave (line 247) | GGWave *& GGWave_instance() { return g_ggWave; }
  function GGWave_mainLoop (line 249) | bool GGWave_mainLoop() {
  function GGWave_deinit (line 302) | bool GGWave_deinit() {
  function main (line 321) | int main(int argc, char** argv) {

FILE: examples/arduino-tx-obsolete/ggwave.h
  function Reset (line 63) | inline void Reset() {
  function Copy (line 79) | inline void Copy(const Poly* src) {
  function at (line 84) | inline uint8_t& at(uint8_t i) const {
  function namespace (line 113) | namespace gf {
  function class (line 332) | class ReedSolomon {
  function EncodeBlock (line 380) | void EncodeBlock(const void* src, void* dst) {
  function Encode (line 434) | void Encode(const void* src, void* dst) {
  type POLY_ID (line 563) | enum POLY_ID {
  function GeneratorPoly (line 592) | void GeneratorPoly() {
  function CalcSyndromes (line 611) | void CalcSyndromes(const Poly *msg) {
  function FindErrataLocator (line 620) | void FindErrataLocator(const Poly *epos) {
  function FindErrorEvaluator (line 645) | void FindErrorEvaluator(const Poly *synd, const Poly *errata_loc, Poly *...
  function CorrectErrata (line 658) | void CorrectErrata(const Poly *synd, const Poly *err_pos, const Poly *ms...
  function FindErrors (line 802) | bool FindErrors(const Poly *error_loc, size_t msg_in_size) {
  function CalcForneySyndromes (line 823) | void CalcForneySyndromes(const Poly *synd, const Poly *erasures_pos, siz...
  function namespace (line 847) | namespace GGWave {

FILE: examples/dr_wav.h
  type drwav_int8 (line 153) | typedef   signed char           drwav_int8;
  type drwav_uint8 (line 154) | typedef unsigned char           drwav_uint8;
  type drwav_int16 (line 155) | typedef   signed short          drwav_int16;
  type drwav_uint16 (line 156) | typedef unsigned short          drwav_uint16;
  type drwav_int32 (line 157) | typedef   signed int            drwav_int32;
  type drwav_uint32 (line 158) | typedef unsigned int            drwav_uint32;
  type drwav_int64 (line 160) | typedef   signed __int64    drwav_int64;
  type drwav_uint64 (line 161) | typedef unsigned __int64    drwav_uint64;
  type drwav_int64 (line 170) | typedef   signed long long  drwav_int64;
  type drwav_uint64 (line 171) | typedef unsigned long long  drwav_uint64;
  type drwav_uint64 (line 177) | typedef drwav_uint64        drwav_uintptr;
  type drwav_uint32 (line 179) | typedef drwav_uint32        drwav_uintptr;
  type drwav_uint8 (line 181) | typedef drwav_uint8             drwav_bool8;
  type drwav_uint32 (line 182) | typedef drwav_uint32            drwav_bool32;
  type drwav_int32 (line 216) | typedef drwav_int32 drwav_result;
  type drwav_seek_origin (line 292) | typedef enum
  type drwav_container (line 298) | typedef enum
  type drwav_chunk_header (line 305) | typedef struct
  type drwav_fmt (line 323) | typedef struct
  type drwav_bool32 (line 405) | typedef drwav_bool32 (* drwav_seek_proc)(void* pUserData, int offset, dr...
  type drwav_uint64 (line 431) | typedef drwav_uint64 (* drwav_chunk_proc)(void* pChunkUserData, drwav_re...
  type drwav_allocation_callbacks (line 433) | typedef struct
  type drwav__memory_stream (line 442) | typedef struct
  type drwav__memory_stream_write (line 450) | typedef struct
  type drwav_data_format (line 459) | typedef struct
  type drwav_smpl_loop (line 470) | typedef struct
  type drwav_smpl (line 480) | typedef struct
  type drwav (line 494) | typedef struct
  function DRWAV_API (line 1066) | DRWAV_API void drwav_version(drwav_uint32* pMajor, drwav_uint32* pMinor,...
  function DRWAV_API (line 1081) | DRWAV_API const char* drwav_version_string(void)
  function DRWAV_INLINE (line 1108) | static DRWAV_INLINE drwav_bool32 drwav__guid_equal(const drwav_uint8 a[1...
  function DRWAV_INLINE (line 1120) | static DRWAV_INLINE drwav_bool32 drwav__fourcc_equal(const drwav_uint8* ...
  function DRWAV_INLINE (line 1131) | static DRWAV_INLINE int drwav__is_little_endian(void)
  function DRWAV_INLINE (line 1143) | static DRWAV_INLINE drwav_uint16 drwav__bytes_to_u16(const drwav_uint8* ...
  function DRWAV_INLINE (line 1148) | static DRWAV_INLINE drwav_int16 drwav__bytes_to_s16(const drwav_uint8* d...
  function DRWAV_INLINE (line 1153) | static DRWAV_INLINE drwav_uint32 drwav__bytes_to_u32(const drwav_uint8* ...
  function DRWAV_INLINE (line 1158) | static DRWAV_INLINE drwav_int32 drwav__bytes_to_s32(const drwav_uint8* d...
  function DRWAV_INLINE (line 1163) | static DRWAV_INLINE drwav_uint64 drwav__bytes_to_u64(const drwav_uint8* ...
  function DRWAV_INLINE (line 1170) | static DRWAV_INLINE drwav_int64 drwav__bytes_to_s64(const drwav_uint8* d...
  function DRWAV_INLINE (line 1175) | static DRWAV_INLINE void drwav__bytes_to_guid(const drwav_uint8* data, d...
  function DRWAV_INLINE (line 1184) | static DRWAV_INLINE drwav_uint16 drwav__bswap16(drwav_uint16 n)
  function DRWAV_INLINE (line 1231) | static DRWAV_INLINE drwav_uint64 drwav__bswap64(drwav_uint64 n)
  function DRWAV_INLINE (line 1255) | static DRWAV_INLINE drwav_int16 drwav__bswap_s16(drwav_int16 n)
  function DRWAV_INLINE (line 1260) | static DRWAV_INLINE void drwav__bswap_samples_s16(drwav_int16* pSamples,...
  function DRWAV_INLINE (line 1269) | static DRWAV_INLINE void drwav__bswap_s24(drwav_uint8* p)
  function DRWAV_INLINE (line 1277) | static DRWAV_INLINE void drwav__bswap_samples_s24(drwav_uint8* pSamples,...
  function DRWAV_INLINE (line 1287) | static DRWAV_INLINE drwav_int32 drwav__bswap_s32(drwav_int32 n)
  function DRWAV_INLINE (line 1292) | static DRWAV_INLINE void drwav__bswap_samples_s32(drwav_int32* pSamples,...
  function DRWAV_INLINE (line 1301) | static DRWAV_INLINE float drwav__bswap_f32(float n)
  function DRWAV_INLINE (line 1313) | static DRWAV_INLINE void drwav__bswap_samples_f32(float* pSamples, drwav...
  function DRWAV_INLINE (line 1322) | static DRWAV_INLINE double drwav__bswap_f64(double n)
  function DRWAV_INLINE (line 1334) | static DRWAV_INLINE void drwav__bswap_samples_f64(double* pSamples, drwa...
  function DRWAV_INLINE (line 1343) | static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_...
  function DRWAV_INLINE (line 1368) | static DRWAV_INLINE void drwav__bswap_samples_ieee(void* pSamples, drwav...
  function DRWAV_INLINE (line 1394) | static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint...
  function drwav__free_default (line 1437) | static void drwav__free_default(void* p, void* pUserData)
  function drwav__free_from_callbacks (line 1492) | static void drwav__free_from_callbacks(void* p, const drwav_allocation_c...
  function drwav_allocation_callbacks (line 1504) | static drwav_allocation_callbacks drwav_copy_allocation_callbacks_or_def...
  function DRWAV_INLINE (line 1521) | static DRWAV_INLINE drwav_bool32 drwav__is_compressed_format_tag(drwav_u...
  function drwav__chunk_padding_size_riff (line 1528) | static unsigned int drwav__chunk_padding_size_riff(drwav_uint64 chunkSize)
  function drwav__chunk_padding_size_w64 (line 1533) | static unsigned int drwav__chunk_padding_size_w64(drwav_uint64 chunkSize)
  function drwav_result (line 1542) | static drwav_result drwav__read_chunk_header(drwav_read_proc onRead, voi...
  function drwav_bool32 (line 1577) | static drwav_bool32 drwav__seek_forward(drwav_seek_proc onSeek, drwav_ui...
  function drwav_bool32 (line 1597) | static drwav_bool32 drwav__seek_from_start(drwav_seek_proc onSeek, drwav...
  function drwav_bool32 (line 1625) | static drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_p...
  function drwav__on_read (line 1735) | static size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, vo...
  function drwav_bool32 (line 1748) | static drwav_bool32 drwav__on_seek(drwav_seek_proc onSeek, void* pUserDa...
  function drwav_uint32 (line 1769) | static drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav* pWav)
  function DRWAV_API (line 1783) | DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt* pFMT)
  function drwav_bool32 (line 1796) | static drwav_bool32 drwav_preinit(drwav* pWav, drwav_read_proc onRead, d...
  function drwav_bool32 (line 1815) | static drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc o...
  function DRWAV_API (line 2239) | DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, d...
  function DRWAV_API (line 2244) | DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead...
  function drwav_uint32 (line 2254) | static drwav_uint32 drwav__riff_chunk_size_riff(drwav_uint64 dataChunkSize)
  function drwav_uint32 (line 2264) | static drwav_uint32 drwav__data_chunk_size_riff(drwav_uint64 dataChunkSize)
  function drwav_uint64 (line 2273) | static drwav_uint64 drwav__riff_chunk_size_w64(drwav_uint64 dataChunkSize)
  function drwav_uint64 (line 2280) | static drwav_uint64 drwav__data_chunk_size_w64(drwav_uint64 dataChunkSize)
  function drwav_uint64 (line 2285) | static drwav_uint64 drwav__riff_chunk_size_rf64(drwav_uint64 dataChunkSize)
  function drwav_uint64 (line 2295) | static drwav_uint64 drwav__data_chunk_size_rf64(drwav_uint64 dataChunkSize)
  function drwav__write (line 2301) | static size_t drwav__write(drwav* pWav, const void* pData, size_t dataSize)
  function drwav__write_u16ne_to_le (line 2310) | static size_t drwav__write_u16ne_to_le(drwav* pWav, drwav_uint16 value)
  function drwav__write_u32ne_to_le (line 2322) | static size_t drwav__write_u32ne_to_le(drwav* pWav, drwav_uint32 value)
  function drwav__write_u64ne_to_le (line 2334) | static size_t drwav__write_u64ne_to_le(drwav* pWav, drwav_uint64 value)
  function drwav_bool32 (line 2347) | static drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_fo...
  function drwav_bool32 (line 2387) | static drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_...
  function DRWAV_API (line 2501) | DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_fo...
  function DRWAV_API (line 2510) | DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const dr...
  function DRWAV_API (line 2519) | DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWa...
  function DRWAV_API (line 2528) | DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_fo...
  function drwav_result (line 2554) | static drwav_result drwav_result_from_errno(int e)
  function drwav_result (line 2956) | static drwav_result drwav_fopen(FILE** ppFile, const char* pFilePath, co...
  function drwav_result (line 3016) | static drwav_result drwav_wfopen(FILE** ppFile, const wchar_t* pFilePath...
  function drwav__on_read_stdio (line 3099) | static size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, si...
  function drwav__on_write_stdio (line 3104) | static size_t drwav__on_write_stdio(void* pUserData, const void* pData, ...
  function drwav_bool32 (line 3109) | static drwav_bool32 drwav__on_seek_stdio(void* pUserData, int offset, dr...
  function DRWAV_API (line 3114) | DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename...
  function drwav_bool32 (line 3120) | static drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pF...
  function DRWAV_API (line 3139) | DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filen...
  function DRWAV_API (line 3150) | DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* fil...
  function DRWAV_API (line 3155) | DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* ...
  function drwav_bool32 (line 3167) | static drwav_bool32 drwav_init_file_write__internal_FILE(drwav* pWav, FI...
  function drwav_bool32 (line 3186) | static drwav_bool32 drwav_init_file_write__internal(drwav* pWav, const c...
  function drwav_bool32 (line 3197) | static drwav_bool32 drwav_init_file_write_w__internal(drwav* pWav, const...
  function DRWAV_API (line 3208) | DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* fi...
  function DRWAV_API (line 3213) | DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, con...
  function DRWAV_API (line 3218) | DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav...
  function DRWAV_API (line 3227) | DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_...
  function DRWAV_API (line 3232) | DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, c...
  function DRWAV_API (line 3237) | DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drw...
  function drwav__on_read_memory (line 3248) | static size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, s...
  function drwav_bool32 (line 3269) | static drwav_bool32 drwav__on_seek_memory(void* pUserData, int offset, d...
  function drwav__on_write_memory (line 3298) | static size_t drwav__on_write_memory(void* pUserData, const void* pDataI...
  function drwav_bool32 (line 3338) | static drwav_bool32 drwav__on_seek_memory_write(void* pUserData, int off...
  function DRWAV_API (line 3367) | DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, ...
  function DRWAV_API (line 3372) | DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* dat...
  function drwav_bool32 (line 3390) | static drwav_bool32 drwav_init_memory_write__internal(drwav* pWav, void*...
  function DRWAV_API (line 3412) | DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppDat...
  function DRWAV_API (line 3417) | DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, v...
  function DRWAV_API (line 3422) | DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drw...
  function DRWAV_API (line 3433) | DRWAV_API drwav_result drwav_uninit(drwav* pWav)
  function DRWAV_API (line 3531) | DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* p...
  function DRWAV_API (line 3585) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint6...
  function DRWAV_API (line 3621) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint6...
  function DRWAV_API (line 3632) | DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 f...
  function DRWAV_API (line 3643) | DRWAV_API drwav_bool32 drwav_seek_to_first_pcm_frame(drwav* pWav)
  function DRWAV_API (line 3670) | DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav* pWav, drwav_uint64...
  function DRWAV_API (line 3774) | DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const...
  function DRWAV_API (line 3789) | DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint...
  function DRWAV_API (line 3827) | DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint...
  function DRWAV_API (line 3883) | DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 ...
  function drwav_uint64 (line 3893) | static drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav* pWav, drwa...
  function drwav_uint64 (line 4073) | static drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav* pWav, drwav_ui...
  function DRWAV_INLINE (line 4269) | static DRWAV_INLINE drwav_int16 drwav__alaw_to_s16(drwav_uint8 sampleIn)
  function DRWAV_INLINE (line 4274) | static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn)
  function drwav__pcm_to_s16 (line 4281) | static void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn,...
  function drwav__ieee_to_s16 (line 4333) | static void drwav__ieee_to_s16(drwav_int16* pOut, const drwav_uint8* pIn...
  function drwav_uint64 (line 4348) | static drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav* pWav, drwav_ui...
  function drwav_uint64 (line 4382) | static drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav* pWav, drwav_u...
  function drwav_uint64 (line 4415) | static drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav* pWav, drwav_u...
  function drwav_uint64 (line 4448) | static drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav* pWav, drwav_...
  function DRWAV_API (line 4481) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav* pWav, drwav_uint...
  function DRWAV_API (line 4523) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav* pWav, drwav_ui...
  function DRWAV_API (line 4533) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav* pWav, drwav_ui...
  function DRWAV_API (line 4544) | DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn...
  function DRWAV_API (line 4556) | DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pI...
  function DRWAV_API (line 4567) | DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pI...
  function DRWAV_API (line 4578) | DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, siz...
  function DRWAV_API (line 4593) | DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, si...
  function DRWAV_API (line 4608) | DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* p...
  function DRWAV_API (line 4616) | DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* ...
  function drwav__pcm_to_f32 (line 4626) | static void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_...
  function drwav__ieee_to_f32 (line 4675) | static void drwav__ieee_to_f32(float* pOut, const drwav_uint8* pIn, size...
  function drwav_uint64 (line 4694) | static drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_ui...
  function drwav_uint64 (line 4722) | static drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav* pWav, drwa...
  function drwav_uint64 (line 4746) | static drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_ui...
  function drwav_uint64 (line 4770) | static drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_u...
  function drwav_uint64 (line 4804) | static drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_u...
  function drwav_uint64 (line 4831) | static drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_...
  function DRWAV_API (line 4859) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint...
  function DRWAV_API (line 4901) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_ui...
  function DRWAV_API (line 4911) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_ui...
  function DRWAV_API (line 4922) | DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size...
  function DRWAV_API (line 4951) | DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, siz...
  function DRWAV_API (line 4964) | DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, siz...
  function DRWAV_API (line 4983) | DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, siz...
  function DRWAV_API (line 4995) | DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t s...
  function DRWAV_API (line 5008) | DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, si...
  function DRWAV_API (line 5021) | DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, s...
  function drwav__pcm_to_s32 (line 5036) | static void drwav__pcm_to_s32(drwav_int32* pOut, const drwav_uint8* pIn,...
  function drwav__ieee_to_s32 (line 5087) | static void drwav__ieee_to_s32(drwav_int32* pOut, const drwav_uint8* pIn...
  function drwav_uint64 (line 5103) | static drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav* pWav, drwav_ui...
  function drwav_uint64 (line 5137) | static drwav_uint64 drwav_read_pcm_frames_s32__msadpcm(drwav* pWav, drwa...
  function drwav_uint64 (line 5161) | static drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav* pWav, drwav_ui...
  function drwav_uint64 (line 5185) | static drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav* pWav, drwav_u...
  function drwav_uint64 (line 5213) | static drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav* pWav, drwav_u...
  function drwav_uint64 (line 5241) | static drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav* pWav, drwav_...
  function DRWAV_API (line 5269) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav* pWav, drwav_uint...
  function DRWAV_API (line 5311) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav* pWav, drwav_ui...
  function DRWAV_API (line 5321) | DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav* pWav, drwav_ui...
  function DRWAV_API (line 5332) | DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn...
  function DRWAV_API (line 5345) | DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pI...
  function DRWAV_API (line 5358) | DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pI...
  function DRWAV_API (line 5376) | DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, siz...
  function DRWAV_API (line 5389) | DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, si...
  function DRWAV_API (line 5402) | DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* p...
  function DRWAV_API (line 5415) | DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* ...
  function drwav_int16 (line 5430) | static drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, un...
  function drwav_int32 (line 5514) | static drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, un...
  function DRWAV_API (line 5558) | DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_pro...
  function DRWAV_API (line 5579) | DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRe...
  function DRWAV_API (line 5600) | DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_pro...
  function DRWAV_API (line 5622) | DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const cha...
  function DRWAV_API (line 5643) | DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* fil...
  function DRWAV_API (line 5664) | DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const cha...
  function DRWAV_API (line 5686) | DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const w...
  function DRWAV_API (line 5707) | DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t...
  function DRWAV_API (line 5728) | DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const w...
  function DRWAV_API (line 5750) | DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const v...
  function DRWAV_API (line 5771) | DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* d...
  function DRWAV_API (line 5792) | DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const v...
  function DRWAV_API (line 5815) | DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAl...
  function DRWAV_API (line 5824) | DRWAV_API drwav_uint16 drwav_bytes_to_u16(const drwav_uint8* data)
  function DRWAV_API (line 5829) | DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8* data)
  function DRWAV_API (line 5834) | DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8* data)
  function DRWAV_API (line 5839) | DRWAV_API drwav_int32 drwav_bytes_to_s32(const drwav_uint8* data)
  function DRWAV_API (line 5844) | DRWAV_API drwav_uint64 drwav_bytes_to_u64(const drwav_uint8* data)
  function DRWAV_API (line 5849) | DRWAV_API drwav_int64 drwav_bytes_to_s64(const drwav_uint8* data)
  function DRWAV_API (line 5855) | DRWAV_API drwav_bool32 drwav_guid_equal(const drwav_uint8 a[16], const d...
  function DRWAV_API (line 5860) | DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const ch...

FILE: examples/ggwave-cli/main.cpp
  function main (line 15) | int main(int argc, char** argv) {

FILE: examples/ggwave-common-sdl2.cpp
  function EMSCRIPTEN_KEEPALIVE (line 35) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 41) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 47) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 50) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 53) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 56) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 59) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 62) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 65) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 68) | EMSCRIPTEN_KEEPALIVE
  function GGWave_setDefaultCaptureDeviceName (line 72) | void GGWave_setDefaultCaptureDeviceName(std::string name) {
  function GGWave_init (line 76) | bool GGWave_init(
  function GGWave_instance (line 234) | std::shared_ptr<GGWave> GGWave_instance() { return g_ggWave; }
  function GGWave_reset (line 236) | void GGWave_reset(void * parameters) {
  function GGWave_mainLoop (line 240) | bool GGWave_mainLoop() {
  function GGWave_deinit (line 284) | bool GGWave_deinit() {

FILE: examples/ggwave-common.cpp
  function dummy (line 13) | void dummy() {}
  function parseCmdArguments (line 16) | std::map<std::string, std::string> parseCmdArguments(int argc, char ** a...
  function readFile (line 30) | std::vector<char> readFile(const char* filename) {
  function getBinaryPath (line 51) | std::string getBinaryPath() {

FILE: examples/ggwave-from-file/main.cpp
  function main (line 12) | int main(int argc, char** argv) {

FILE: examples/ggwave-rx/main.cpp
  function main (line 11) | int main(int argc, char** argv) {

FILE: examples/ggwave-to-file/ggwave-to-file.py
  function ggwave (line 5) | def ggwave(message: str,

FILE: examples/ggwave-to-file/main.cpp
  function main (line 12) | int main(int argc, char** argv) {

FILE: examples/ggwave-wasm/main.cpp
  function update (line 7) | void update() {
  function main (line 11) | int main(int , char** argv) {

FILE: examples/ggwave-wasm/main.js
  function transmitText (line 1) | function transmitText(sText) {
  function updatePeerInfo (line 16) | function updatePeerInfo() {
  function updateRx (line 46) | function updateRx() {

FILE: examples/pfd/pfd.h
  type class (line 54) | enum class
  type class (line 65) | enum class
  type class (line 75) | enum class
  function opt (line 84) | enum class opt : uint8_t
  function class (line 102) | class settings

FILE: examples/r2t2/main.cpp
  function processTone (line 19) | void processTone(int fd, double freq_hz, long duration_ms, bool useBeep,...
  function main (line 46) | int main(int argc, char** argv) {

FILE: examples/r2t2/main.js
  function transmitText (line 1) | function transmitText(sText) {
  function updatePeerInfo (line 16) | function updatePeerInfo() {
  function updateRx (line 46) | function updateRx() {

FILE: examples/r2t2/r2t2-rx.cpp
  function mainUpdate (line 38) | void mainUpdate(void *) {
  function EMSCRIPTEN_KEEPALIVE (line 45) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 51) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 57) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 60) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 63) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 66) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 69) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 72) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 75) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 78) | EMSCRIPTEN_KEEPALIVE
  function GGWave_setDefaultCaptureDeviceName (line 82) | void GGWave_setDefaultCaptureDeviceName(std::string name) {
  function GGWave_init (line 86) | bool GGWave_init(
  function GGWave (line 246) | GGWave *& GGWave_instance() { return g_ggWave; }
  function GGWave_mainLoop (line 248) | bool GGWave_mainLoop() {
  function GGWave_deinit (line 292) | bool GGWave_deinit() {
  function main (line 311) | int main(int argc, char** argv) {

FILE: examples/rp2040-rx/mic-analog.cpp
  function analog_microphone_init (line 36) | int analog_microphone_init(const struct analog_microphone_config* config) {
  function analog_microphone_deinit (line 102) | void analog_microphone_deinit() {
  function analog_microphone_start (line 118) | int analog_microphone_start() {
  function analog_microphone_stop (line 144) | void analog_microphone_stop() {
  function analog_dma_handler (line 158) | static void analog_dma_handler() {
  function analog_microphone_set_samples_ready_handler (line 184) | void analog_microphone_set_samples_ready_handler(analog_samples_ready_ha...
  function analog_microphone_read (line 188) | int analog_microphone_read(int16_t* buffer, size_t samples) {

FILE: examples/rp2040-rx/mic-analog.h
  type analog_microphone_config (line 16) | struct analog_microphone_config {
  type analog_microphone_config (line 23) | struct analog_microphone_config

FILE: examples/spectrogram/main.cpp
  type FreqData (line 31) | struct FreqData {
  function GGWave_setDefaultCaptureDeviceName (line 60) | void GGWave_setDefaultCaptureDeviceName(std::string name) {
  function GGWave_init (line 64) | bool GGWave_init(
  function GGWave_mainLoop (line 174) | bool GGWave_mainLoop() {
  function GGWave_deinit (line 251) | bool GGWave_deinit() {
  function ImGui_BeginFrame (line 267) | bool ImGui_BeginFrame(SDL_Window * window) {
  function ImGui_EndFrame (line 281) | bool ImGui_EndFrame(SDL_Window * window) {
  function ImGui_SetStyle (line 297) | bool ImGui_SetStyle() {
  function mainUpdate (line 367) | void mainUpdate(void *) {
  function EMSCRIPTEN_KEEPALIVE (line 374) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 379) | EMSCRIPTEN_KEEPALIVE
  function main (line 385) | int main(int argc, char** argv) {

FILE: examples/third-party/imgui/imgui-extra/imgui_impl.cpp
  function ImGui_PreInit (line 20) | bool ImGui_PreInit() {
  function ImGuiContext (line 51) | ImGuiContext* ImGui_Init(SDL_Window* window, SDL_GLContext gl_context) {
  function ImGui_Shutdown (line 100) | void ImGui_Shutdown() { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplSDL2_Shu...
  function ImGui_NewFrame (line 101) | void ImGui_NewFrame(SDL_Window* window) { ImGui_ImplOpenGL3_NewFrame(); ...
  function ImGui_ProcessEvent (line 102) | bool ImGui_ProcessEvent(const SDL_Event* event) { return ImGui_ImplSDL2_...
  function ImGui_RenderDrawData (line 104) | void ImGui_RenderDrawData(ImDrawData* draw_data)    { ImGui_ImplOpenGL3_...
  function ImGui_CreateFontsTexture (line 106) | bool ImGui_CreateFontsTexture()     { return ImGui_ImplOpenGL3_CreateFon...
  function ImGui_DestroyFontsTexture (line 107) | void ImGui_DestroyFontsTexture()    { ImGui_ImplOpenGL3_DestroyFontsText...
  function ImGui_CreateDeviceObjects (line 108) | bool ImGui_CreateDeviceObjects()    { return ImGui_ImplOpenGL3_CreateDev...
  function ImGui_DestroyDeviceObjects (line 109) | void ImGui_DestroyDeviceObjects()   { ImGui_ImplOpenGL3_DestroyDeviceObj...
  function ImGui_SaveState (line 111) | void ImGui_SaveState(int id) { ImGui_ImplSDL2_SaveState(id); ImGui_ImplO...
  function ImGui_LoadState (line 112) | void ImGui_LoadState(int id) { ImGui_ImplSDL2_LoadState(id); ImGui_ImplO...

FILE: examples/third-party/imgui/imgui-extra/imgui_impl.h
  type SDL_Window (line 13) | struct SDL_Window
  type SDL_Event (line 15) | typedef union SDL_Event SDL_Event;

FILE: examples/third-party/imgui/imgui-extra/imgui_impl_opengl3.cpp
  type State (line 148) | struct State {
  function ImGui_ImplOpenGL3_SaveState (line 158) | void ImGui_ImplOpenGL3_SaveState(int id) {
  function ImGui_ImplOpenGL3_LoadState (line 175) | void ImGui_ImplOpenGL3_LoadState(int id) {
  function ImGui_ImplOpenGL3_Init (line 192) | bool    ImGui_ImplOpenGL3_Init(const char* glsl_version)
  function ImGui_ImplOpenGL3_Shutdown (line 256) | void    ImGui_ImplOpenGL3_Shutdown()
  function ImGui_ImplOpenGL3_NewFrame (line 261) | void    ImGui_ImplOpenGL3_NewFrame()
  function ImGui_ImplOpenGL3_SetupRenderState (line 267) | static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, in...
  function ImGui_ImplOpenGL3_RenderDrawData (line 320) | void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
  function ImGui_ImplOpenGL3_CreateFontsTexture (line 455) | bool ImGui_ImplOpenGL3_CreateFontsTexture()
  function ImGui_ImplOpenGL3_DestroyFontsTexture (line 484) | void ImGui_ImplOpenGL3_DestroyFontsTexture()
  function CheckShader (line 496) | static bool CheckShader(GLuint handle, const char* desc)
  function CheckProgram (line 514) | static bool CheckProgram(GLuint handle, const char* desc)
  function ImGui_ImplOpenGL3_CreateDeviceObjects (line 531) | bool    ImGui_ImplOpenGL3_CreateDeviceObjects()
  function ImGui_ImplOpenGL3_DestroyDeviceObjects (line 711) | void    ImGui_ImplOpenGL3_DestroyDeviceObjects()

FILE: examples/third-party/imgui/imgui-extra/imgui_impl_sdl.cpp
  type State (line 69) | struct State {
  function ImGui_ImplSDL2_SaveState (line 80) | void ImGui_ImplSDL2_SaveState(int id) {
  function ImGui_ImplSDL2_LoadState (line 95) | void ImGui_ImplSDL2_LoadState(int id) {
  function ImGui_ImplSDL2_SetClipboardText (line 118) | static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
  function ImGui_ImplSDL2_ProcessEvent (line 128) | bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
  function ImGui_ImplSDL2_Init (line 173) | static bool ImGui_ImplSDL2_Init(SDL_Window* window)
  function ImGui_ImplSDL2_InitForOpenGL (line 237) | bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
  function ImGui_ImplSDL2_InitForVulkan (line 243) | bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
  function ImGui_ImplSDL2_InitForD3D (line 251) | bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
  function ImGui_ImplSDL2_InitForMetal (line 259) | bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
  function ImGui_ImplSDL2_Shutdown (line 264) | void ImGui_ImplSDL2_Shutdown()
  function ImGui_ImplSDL2_UpdateMousePosAndButtons (line 279) | static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
  function ImGui_ImplSDL2_UpdateMouseCursor (line 324) | static void ImGui_ImplSDL2_UpdateMouseCursor()
  function ImGui_ImplSDL2_UpdateGamepads (line 344) | static void ImGui_ImplSDL2_UpdateGamepads()
  function ImGui_ImplSDL2_NewFrame (line 385) | void ImGui_ImplSDL2_NewFrame(SDL_Window* window)

FILE: examples/third-party/imgui/imgui-extra/imgui_impl_sdl.h
  type SDL_Window (line 19) | struct SDL_Window
  type SDL_Event (line 20) | typedef union SDL_Event SDL_Event;

FILE: examples/waver/common.cpp
  function ScrollWhenDraggingOnVoid (line 50) | bool ScrollWhenDraggingOnVoid(const ImVec2& delta, ImGuiMouseButton mous...
  type ImGui (line 71) | namespace ImGui {
    function ButtonDisabled (line 72) | bool ButtonDisabled(const char* label, const ImVec2& size = ImVec2(0, ...
    function ButtonDisablable (line 94) | bool ButtonDisablable(const char* label, const ImVec2& size = ImVec2(0...
    function ButtonSelected (line 102) | bool ButtonSelected(const char* label, const ImVec2& size = ImVec2(0, ...
    function ButtonSelectable (line 111) | bool ButtonSelectable(const char* label, const ImVec2& size = ImVec2(0...
  type Message (line 122) | struct Message {
    type Type (line 123) | enum Type {
  type GGWaveStats (line 138) | struct GGWaveStats {
  type State (line 153) | struct State {
    type Flags (line 156) | struct Flags {
      method clear (line 163) | void clear() { memset(this, 0, sizeof(Flags)); }
    method apply (line 166) | void apply(State & dst) {
  type Input (line 213) | struct Input {
    type Flags (line 216) | struct Flags {
      method clear (line 223) | void clear() { memset(this, 0, sizeof(Flags)); }
    method apply (line 226) | void apply(Input & dst) {
  type Buffer (line 283) | struct Buffer {
  type BroadcastInfo (line 297) | struct BroadcastInfo {
  type FileInfoExtended (line 308) | struct FileInfoExtended {
  function getShareId (line 344) | int getShareId() {
  function ShareInfo (line 348) | ShareInfo getShareInfo() {
  function getOpenId (line 352) | int getOpenId() {
  function OpenInfo (line 356) | OpenInfo getOpenInfo() {
  function getDeleteId (line 360) | int getDeleteId() {
  function DeleteInfo (line 364) | DeleteInfo getDeleteInfo() {
  function getReceivedId (line 368) | int getReceivedId() {
  function getReceiveInfos (line 372) | std::vector<ReceiveInfo> getReceiveInfos() {
  function confirmReceive (line 391) | bool confirmReceive(const char * uri) {
  function clearAllFiles (line 402) | void clearAllFiles() {
  function clearFile (line 406) | void clearFile(const char * uri) {
  function addFile (line 410) | void addFile(
  function addFile (line 429) | void addFile(
  function generateFileBroadcastMessage (line 446) | std::string generateFileBroadcastMessage() {
  function BroadcastInfo (line 486) | BroadcastInfo parseBroadcastInfo(const std::string & message) {
  function isFileBroadcastMessage (line 509) | bool isFileBroadcastMessage(const std::string & message) {
  function initMainAndRunCore (line 529) | std::thread initMainAndRunCore() {
  function initMain (line 541) | void initMain() {
  function updateCore (line 596) | void updateCore() {
  function renderMain (line 782) | void renderMain() {
  function deinitMain (line 2237) | void deinitMain() {

FILE: examples/waver/common.h
  type ShareInfo (line 17) | struct ShareInfo {
  type OpenInfo (line 29) | struct OpenInfo {
  type DeleteInfo (line 41) | struct DeleteInfo {
  type ReceiveInfo (line 51) | struct ReceiveInfo {

FILE: examples/waver/interface-emscripten.cpp
  function interface_addFile (line 5) | void interface_addFile(
  function interface_loadAllFiles (line 12) | void interface_loadAllFiles() {
  function interface_shareFile (line 15) | void interface_shareFile(
  function interface_openFile (line 22) | void interface_openFile(
  function interface_deleteFile (line 29) | void interface_deleteFile(
  function interface_receiveFile (line 34) | void interface_receiveFile(
  function interface_needReloadFiles (line 41) | bool interface_needReloadFiles() {

FILE: examples/waver/interface-unix.cpp
  function interface_addFile (line 7) | void interface_addFile(
  function interface_loadAllFiles (line 14) | void interface_loadAllFiles() {
  function interface_shareFile (line 17) | void interface_shareFile(
  function interface_openFile (line 34) | void interface_openFile(
  function interface_deleteFile (line 41) | void interface_deleteFile(
  function interface_receiveFile (line 46) | void interface_receiveFile(
  function interface_needReloadFiles (line 54) | bool interface_needReloadFiles() {

FILE: examples/waver/interface.cpp
  function updateMain (line 9) | void updateMain() {

FILE: examples/waver/main.cpp
  function ImGui_tryLoadFont (line 25) | bool ImGui_tryLoadFont(const std::string & filename, float size = 14.0f,...
  function ImGui_BeginFrame (line 48) | bool ImGui_BeginFrame(SDL_Window * window) {
  function ImGui_EndFrame (line 77) | bool ImGui_EndFrame(SDL_Window * window) {
  function ImGui_SetStyle (line 93) | bool ImGui_SetStyle() {
  function mainUpdate (line 165) | void mainUpdate(void *) {
  function EMSCRIPTEN_KEEPALIVE (line 172) | EMSCRIPTEN_KEEPALIVE
  function EMSCRIPTEN_KEEPALIVE (line 177) | EMSCRIPTEN_KEEPALIVE
  function main (line 183) | int main(int argc, char** argv) {

FILE: include/ggwave/ggwave.h
  type ggwave_SampleFormat (line 33) | typedef enum {
  type ggwave_ProtocolId (line 43) | typedef enum {
  type ggwave_Filter (line 75) | typedef enum {
  type ggwave_Parameters (line 131) | typedef struct {
  type ggwave_Instance (line 146) | typedef int ggwave_Instance;
  function T (line 373) | const T & operator[](int i) const { return m_data[i]; }
  function T (line 376) | T * data() const { return m_data; }
  function T (line 378) | T * begin() const { return m_data; }
  function T (line 379) | T * end() const { return m_data + m_size; }
  function class (line 421) | class GGWave {
  function txDuration_ms (line 457) | int txDuration_ms(int samplesPerFrame, float sampleRate) const {
  type Protocols (line 465) | struct Protocols
  function empty (line 470) | struct Protocols {
  function Tones (line 719) | const Tones txTones() const;
  type Rx (line 931) | struct Rx {
  type Tx (line 981) | struct Tx {

FILE: src/fft.h
  function rdft (line 83) | void rdft(int n, int isgn, float *a, int *ip, float *w)
  function makewt (line 133) | void makewt(int nw, int *ip, float *w)
  function makect (line 163) | void makect(int nc, int *ip, float *c)
  function bitrv2 (line 185) | void bitrv2(int n, int *ip, float *a)
  function bitrv2conj (line 285) | void bitrv2conj(int n, int *ip, float *a)
  function cftfsub (line 394) | void cftfsub(int n, float *a, float *w)
  function cftbsub (line 446) | void cftbsub(int n, float *a, float *w)
  function cft1st (line 498) | void cft1st(int n, float *a, float *w)
  function cftmdl (line 603) | void cftmdl(int n, int l, float *a, float *w)
  function rftfsub (line 730) | void rftfsub(int n, float *a, int nc, float *c)
  function rftbsub (line 755) | void rftbsub(int n, float *a, int nc, float *c)

FILE: src/ggwave.cpp
  function linear_interp (line 41) | double linear_interp(double first_number, double second_number, double f...
  function ggwave_setLogFile (line 48) | void ggwave_setLogFile(void * fptr) {
  function ggwave_Parameters (line 53) | ggwave_Parameters ggwave_getDefaultParameters(void) {
  function ggwave_Instance (line 58) | ggwave_Instance ggwave_init(ggwave_Parameters parameters) {
  function ggwave_free (line 82) | void ggwave_free(ggwave_Instance id) {
  function ggwave_encode (line 94) | int ggwave_encode(
  function ggwave_decode (line 138) | int ggwave_decode(
  function ggwave_ndecode (line 164) | int ggwave_ndecode(
  function ggwave_rxToggleProtocol (line 194) | void ggwave_rxToggleProtocol(
  function ggwave_txToggleProtocol (line 201) | void ggwave_txToggleProtocol(
  function ggwave_rxProtocolSetFreqStart (line 208) | void ggwave_rxProtocolSetFreqStart(
  function ggwave_txProtocolSetFreqStart (line 215) | void ggwave_txProtocolSetFreqStart(
  function ggwave_rxDurationFrames (line 222) | int ggwave_rxDurationFrames(ggwave_Instance id) {
  function getDSSMagic (line 243) | uint8_t getDSSMagic(int i) {
  function FFT (line 251) | void FFT(float * f, int N, int * wi, float * wf) {
  function FFT (line 255) | void FFT(const float * src, float * dst, int N, int * wi, float * wf) {
  function addAmplitudeSmooth (line 261) | inline void addAmplitudeSmooth(
  function getECCBytesForLength (line 284) | int getECCBytesForLength(int len) {
  function bytesForSampleFormat (line 288) | int bytesForSampleFormat(GGWave::SampleFormat sampleFormat) {
  type ggvector<int16_t> (line 334) | struct ggvector<int16_t>
  function ggalloc (line 431) | void ggalloc(ggvector<T> & v, int n, void * buf, int & bufSize) {
  function ggalloc (line 444) | void ggalloc(ggmatrix<T> & v, int n, int m, void * buf, int & bufSize) {

FILE: src/reed-solomon/gf.hpp
  type RS (line 15) | namespace RS {
    type gf (line 17) | namespace gf {
      function add (line 86) | inline uint8_t add(uint8_t x, uint8_t y) {
      function sub (line 95) | inline uint8_t sub(uint8_t x, uint8_t y) {
      function mul (line 103) | inline uint8_t mul(uint16_t x, uint16_t y){
      function div (line 117) | inline uint8_t div(uint8_t x, uint8_t y){
      function pow (line 131) | inline uint8_t pow(uint8_t x, intmax_t power){
      function inverse (line 150) | inline uint8_t inverse(uint8_t x){
      function poly_scale (line 166) | inline void
      function poly_add (line 178) | inline void
      function poly_mul (line 197) | inline void
      function poly_div (line 214) | inline void
      function poly_eval (line 242) | inline int8_t

FILE: src/reed-solomon/poly.hpp
  type RS (line 13) | namespace RS {
    type Poly (line 15) | struct Poly {
      method Poly (line 16) | Poly()
      method Poly (line 19) | Poly(uint8_t id, uint16_t offset, uint8_t size) \
      method Append (line 25) | inline bool Append(uint8_t num) {
      method Init (line 32) | inline void Init(uint8_t id, uint16_t offset, uint8_t size, uint8_t*...
      method Reset (line 41) | inline void Reset() {
      method Set (line 49) | inline void Set(const uint8_t* src, uint8_t len, uint8_t offset = 0) {
      method Copy (line 57) | inline void Copy(const Poly* src) {
      method id (line 67) | inline uint8_t id() const {
      method size (line 71) | inline uint8_t size() const {

FILE: src/reed-solomon/rs.hpp
  type RS (line 17) | namespace RS {
    class ReedSolomon (line 22) | class ReedSolomon {
      method getWorkSize_bytes (line 33) | static size_t getWorkSize_bytes(uint8_t msg_length, uint8_t ecc_leng...
      method ReedSolomon (line 37) | ReedSolomon(uint8_t msg_length_p, uint8_t ecc_length_p, uint8_t * he...
      method EncodeBlock (line 86) | void EncodeBlock(const void* src, void* dst) {
      method Encode (line 139) | void Encode(const void* src, void* dst) {
      method DecodeBlock (line 156) | int DecodeBlock(const void* src, const void* ecc, void* dst, uint8_t...
      method Decode (line 256) | int Decode(const void* src, void* dst, uint8_t* erase_pos = NULL, si...
      type POLY_ID (line 267) | enum POLY_ID {
      method GeneratorPoly (line 296) | void GeneratorPoly() {
      method CalcSyndromes (line 315) | void CalcSyndromes(const Poly *msg) {
      method FindErrataLocator (line 324) | void FindErrataLocator(const Poly *epos) {
      method FindErrorEvaluator (line 349) | void FindErrorEvaluator(const Poly *synd, const Poly *errata_loc, Po...
      method CorrectErrata (line 362) | void CorrectErrata(const Poly *synd, const Poly *err_pos, const Poly...
      method FindErrorLocator (line 441) | bool FindErrorLocator(const Poly *synd, Poly *erase_loc = NULL, size...
      method FindErrors (line 506) | bool FindErrors(const Poly *error_loc, size_t msg_in_size) {
      method CalcForneySyndromes (line 527) | void CalcForneySyndromes(const Poly *synd, const Poly *erasures_pos,...

FILE: tests/test-ggwave.c
  function main (line 16) | int main() {

FILE: tests/test-ggwave.cpp
  function frand (line 14) | float frand() { return float(rand()%RAND_MAX)*iRandMax; }
  function convert (line 50) | void convert(std::vector<uint8_t> & src) {
  function main (line 63) | int main(int argc, char ** argv) {
Condensed preview — 154 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,278K chars).
[
  {
    "path": ".clang-format",
    "chars": 354,
    "preview": "---\nBasedOnStyle: Google\nIndentWidth: '4'\nDerivePointerAlignment: false\nPointerAlignment: Middle\nColumnLimit: 160\nAllow"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 8374,
    "preview": "name: CI\non: [push]\n\njobs:\n\n    ubuntu-24_04-python3-ggwave-deb:\n        runs-on: ubuntu-24.04\n\n        steps:\n         "
  },
  {
    "path": ".gitignore",
    "chars": 110,
    "preview": "build\nbuild-*\ncompile_commands.json\n.exrc\n.clangd\n.cache\n.vimspector.json\n.*.swp\n.ycm_extra_conf.py\n.DS_Store\n"
  },
  {
    "path": ".gitmodules",
    "chars": 344,
    "preview": "[submodule \"examples/third-party/imgui/imgui\"]\n\tpath = examples/third-party/imgui/imgui\n\turl = https://github.com/ocornu"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 2143,
    "preview": "# Changelog\n\n## [Unreleased]\n\n## [v0.4.0] - 2022-07-05\n\n**This release introduces some breaking changes in the C and C++"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 6107,
    "preview": "cmake_minimum_required (VERSION 3.10)\nproject(ggwave VERSION 0.4.2)\n\nset(GGWAVE_VERSION_PYTHON 0.4.2)\n\nset(CMAKE_EXPORT_"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "MIT License\n\nCopyright (c) 2020 Georgi Gerganov\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README-tmpl.md",
    "chars": 11861,
    "preview": "# ggwave\n\n[![Actions Status](https://github.com/ggerganov/ggwave/workflows/CI/badge.svg)](https://github.com/ggerganov/g"
  },
  {
    "path": "README.md",
    "chars": 12293,
    "preview": "# ggwave\n\n[![Actions Status](https://github.com/ggerganov/ggwave/workflows/CI/badge.svg)](https://github.com/ggerganov/g"
  },
  {
    "path": "bindings/CMakeLists.txt",
    "chars": 3052,
    "preview": "if (EMSCRIPTEN)\n    add_subdirectory(javascript)\n\n    add_custom_command(\n        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/jav"
  },
  {
    "path": "bindings/javascript/.gitignore",
    "chars": 12,
    "preview": "publish.log\n"
  },
  {
    "path": "bindings/javascript/CMakeLists.txt",
    "chars": 680,
    "preview": "set(TARGET libggwave)\n\nadd_executable(${TARGET}\n    emscripten.cpp\n    )\n\ntarget_link_libraries(${TARGET} PRIVATE\n    gg"
  },
  {
    "path": "bindings/javascript/README.md",
    "chars": 962,
    "preview": "# ggwave\n\nTiny data-over-sound library.\n\n- Audible and ultrasound transmissions available\n- Bandwidth of 8-16 bytes/s (d"
  },
  {
    "path": "bindings/javascript/emscripten.cpp",
    "chars": 7194,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include <emscripten.h>\n#include <emscripten/bind.h>\n\nEMSCRIPTEN_BINDINGS(ggwave) {\n    emsc"
  },
  {
    "path": "bindings/javascript/ggwave.js",
    "chars": 148131,
    "preview": "\nvar ggwave_factory = (() => {\n  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.c"
  },
  {
    "path": "bindings/javascript/package-tmpl.json",
    "chars": 585,
    "preview": "{\n  \"name\": \"ggwave\",\n  \"version\": \"@PROJECT_VERSION@\",\n  \"description\": \"Tiny data-over-sound library\",\n  \"main\": \"ggwa"
  },
  {
    "path": "bindings/javascript/package.json",
    "chars": 573,
    "preview": "{\n  \"name\": \"ggwave\",\n  \"version\": \"0.4.2\",\n  \"description\": \"Tiny data-over-sound library\",\n  \"main\": \"ggwave.js\",\n  \"s"
  },
  {
    "path": "bindings/python/.gitignore",
    "chars": 109,
    "preview": "ggwave.so\nREADME.rst\nggwave.bycython.cpp\nggwave.cpython-*-x86_64-linux-gnu.so\nggwave/\nggwave.egg-info/\ndist/\n"
  },
  {
    "path": "bindings/python/MANIFEST.in",
    "chars": 95,
    "preview": "recursive-include ggwave/include *\nrecursive-include ggwave/src/ *\ninclude *.pxd\ninclude *.pyx\n"
  },
  {
    "path": "bindings/python/Makefile",
    "chars": 2426,
    "preview": "default: build\n\nPKG_NAME := ggwave\nDEST := dist/\nVER := $(shell cat setup.py | grep version |cut -d\\\"  -f2)\nVERSION := $"
  },
  {
    "path": "bindings/python/README-tmpl.rst",
    "chars": 3731,
    "preview": "..  [[[cog\n\n    import cog\n    import ggwave\n\n    def indent(text, indentation = \"    \"):\n        return indentation + t"
  },
  {
    "path": "bindings/python/README.md",
    "chars": 1900,
    "preview": "# ggwave python package\n\nThis README contains only development information, you can check out full README (README.rst) f"
  },
  {
    "path": "bindings/python/cggwave.pxd",
    "chars": 2517,
    "preview": "cdef extern from \"ggwave.h\" nogil:\n\n    ctypedef enum ggwave_SampleFormat:\n        GGWAVE_SAMPLE_FORMAT_UNDEFINED,\n     "
  },
  {
    "path": "bindings/python/debian/changelog",
    "chars": 137,
    "preview": "ggwave (0.4.2-0) unstable; urgency=low\n\n  * Initial release\n\n --  Georgi Gerganov <ggerganov@gmail.com>  Sat, 15 Mar 202"
  },
  {
    "path": "bindings/python/debian/control",
    "chars": 1023,
    "preview": "Source: ggwave\nSection: python\nPriority: optional\nMaintainer: Georgi Gerganov <ggerganov@gmail.com>\nBuild-Depends: debhe"
  },
  {
    "path": "bindings/python/debian/copyright",
    "chars": 362,
    "preview": "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\nUpstream-Name: ggwave\nUpstream-Contact: Georg"
  },
  {
    "path": "bindings/python/debian/python3-ggwave.docs",
    "chars": 11,
    "preview": "README.rst\n"
  },
  {
    "path": "bindings/python/debian/rules",
    "chars": 95,
    "preview": "#! /usr/bin/make -f\n\nexport PYBUILD_NAME=ggwave\n%:\n\tdh $@ --with python3 --buildsystem=pybuild\n"
  },
  {
    "path": "bindings/python/debian/source/format",
    "chars": 12,
    "preview": "3.0 (quilt)\n"
  },
  {
    "path": "bindings/python/debian/source/options",
    "chars": 50,
    "preview": "extend-diff-ignore=\"^[^/]+.(egg-info|dist-info)/\"\n"
  },
  {
    "path": "bindings/python/ggwave.pyx",
    "chars": 2155,
    "preview": "# cython: language_level=3str\ncimport cython\n\nfrom libc.stdio cimport stderr\nfrom cpython.mem cimport PyMem_Malloc, PyMe"
  },
  {
    "path": "bindings/python/setup-tmpl.py",
    "chars": 1840,
    "preview": "from setuptools import setup, Extension\nfrom codecs import open\nimport os\n\ncmdclass = {}\nlong_description = \"\"\n\n# Build "
  },
  {
    "path": "bindings/python/setup.py",
    "chars": 1822,
    "preview": "from setuptools import setup, Extension\nfrom codecs import open\nimport os\n\ncmdclass = {}\nlong_description = \"\"\n\n# Build "
  },
  {
    "path": "bindings/python/test.py",
    "chars": 281,
    "preview": "import sys\nimport ggwave\n\ntestFailed = False\n\nggwave.disableLog()\nggwave.enableLog()\n\nsamples = ggwave.encode(\"hello pyt"
  },
  {
    "path": "cmake/BuildTypes.cmake",
    "chars": 2037,
    "preview": "# Add new build types\n\n# ReleaseGG - Release with enabled asserts\n\nSET(CMAKE_CXX_FLAGS_RELEASEGG\n    \"-O3\"\n    CACHE STR"
  },
  {
    "path": "cmake/GitVars.cmake",
    "chars": 717,
    "preview": "find_package(Git)\n\n# the commit's SHA1\nexecute_process(COMMAND\n    \"${GIT_EXECUTABLE}\" describe --match=NeVeRmAtCh --alw"
  },
  {
    "path": "cmake/sdl2/FindSDL2.cmake",
    "chars": 7476,
    "preview": "# Distributed under the OSI-approved BSD 3-Clause License. See accompanying\n# file Copyright.txt or https://cmake.org/li"
  },
  {
    "path": "examples/CMakeLists.txt",
    "chars": 2797,
    "preview": "# dependencies\n\nfind_package(Threads REQUIRED)\n\nif (GGWAVE_SUPPORT_SDL2)\n    # SDL2\n\n    if (EMSCRIPTEN)\n        set(CMA"
  },
  {
    "path": "examples/arduino-rx/.gitignore",
    "chars": 63,
    "preview": "ggwave\nggwave.cpp\nfft.h\nresampler.h\nresampler.cpp\nreed-solomon\n"
  },
  {
    "path": "examples/arduino-rx/CMakeLists.txt",
    "chars": 870,
    "preview": "#\n# arduino-rx\n\n#configure_file(${CMAKE_SOURCE_DIR}/include/ggwave/ggwave.h   ${CMAKE_CURRENT_SOURCE_DIR}/ggwave.h      "
  },
  {
    "path": "examples/arduino-rx/README.md",
    "chars": 1093,
    "preview": "# arduino-rx\n\nThis is a sample project for receiving and transmitting audio data using [Arduino RP2040](https://docs.ard"
  },
  {
    "path": "examples/arduino-rx/arduino-rx.ino",
    "chars": 13745,
    "preview": "// arduino-rx\n//\n// Sample sketch for receiving data using \"ggwave\"\n//\n// Tested with:\n//   - Arduino Nano RP2040 Connec"
  },
  {
    "path": "examples/arduino-rx-web/CMakeLists.txt",
    "chars": 631,
    "preview": "#\n# arduino-rx-web\n\nset(TARGET arduino-rx-web)\n\nif (NOT EMSCRIPTEN)\n    add_executable(${TARGET}\n        arduino-rx-web."
  },
  {
    "path": "examples/arduino-rx-web/README.md",
    "chars": 363,
    "preview": "# arduino-rx-web\n\nA simple web page to receive the data from the [arduino-tx](https://github.com/ggerganov/ggwave/tree/m"
  },
  {
    "path": "examples/arduino-rx-web/arduino-rx-web.cpp",
    "chars": 13362,
    "preview": "#include \"ggwave-common.h\"\n\n#include \"ggwave/ggwave.h\"\n\n#ifdef __EMSCRIPTEN__\n#include \"build_timestamp.h\"\n#include <ems"
  },
  {
    "path": "examples/arduino-rx-web/index-tmpl.html",
    "chars": 9061,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <title>ggwave : arduino-rx</title>\n\n        <style>\n            ."
  },
  {
    "path": "examples/arduino-tx/.gitignore",
    "chars": 63,
    "preview": "ggwave\nggwave.cpp\nfft.h\nresampler.h\nresampler.cpp\nreed-solomon\n"
  },
  {
    "path": "examples/arduino-tx/CMakeLists.txt",
    "chars": 870,
    "preview": "#\n# arduino-tx\n\n#configure_file(${CMAKE_SOURCE_DIR}/include/ggwave/ggwave.h   ${CMAKE_CURRENT_SOURCE_DIR}/ggwave.h      "
  },
  {
    "path": "examples/arduino-tx/README.md",
    "chars": 539,
    "preview": "# arduino-tx\n\nThis is a sample project for transmitting data via sound using [Arduino Uno](https://store.arduino.cc/prod"
  },
  {
    "path": "examples/arduino-tx/arduino-tx.ino",
    "chars": 5845,
    "preview": "// arduino-tx\n//\n// Sample sketch for transmitting data using \"ggwave\"\n//\n// Tested with:\n//   - Arduino Uno R3\n//   - A"
  },
  {
    "path": "examples/arduino-tx-obsolete/.gitignore",
    "chars": 63,
    "preview": "ggwave\nggwave.cpp\nfft.h\nresampler.h\nresampler.cpp\nreed-solomon\n"
  },
  {
    "path": "examples/arduino-tx-obsolete/CMakeLists.txt",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/arduino-tx-obsolete/arduino-tx.ino",
    "chars": 2752,
    "preview": "// This example uses a custom ggwave imlpementation specifically for Arduino UNO.\n// Since the Arduino UNO has only 2KB "
  },
  {
    "path": "examples/arduino-tx-obsolete/ggwave.h",
    "chars": 32247,
    "preview": "#pragma once\n\n//\n// The code in the RS namespace provides Reed-Solomon based error correction.\n// The code is taken from"
  },
  {
    "path": "examples/buttons/CMakeLists.txt",
    "chars": 277,
    "preview": "set(TARGET buttons)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/index-tmpl.html       ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/"
  },
  {
    "path": "examples/buttons/README.md",
    "chars": 152,
    "preview": "# buttons\n\nRecord and send commands via [Talking buttons](https://github.com/ggerganov/ggwave/discussions/27)\n\nLive demo"
  },
  {
    "path": "examples/buttons/index-tmpl.html",
    "chars": 9266,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <title>ggwave : buttons</title>\n    </head>\n    <body>\n        <d"
  },
  {
    "path": "examples/dr_wav.h",
    "chars": 241358,
    "preview": "/*\nWAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.\ndr_wav"
  },
  {
    "path": "examples/esp32-rx/.gitignore",
    "chars": 63,
    "preview": "ggwave\nggwave.cpp\nfft.h\nresampler.h\nresampler.cpp\nreed-solomon\n"
  },
  {
    "path": "examples/esp32-rx/CMakeLists.txt",
    "chars": 868,
    "preview": "#\n# esp32-rx\n\n#configure_file(${CMAKE_SOURCE_DIR}/include/ggwave/ggwave.h   ${CMAKE_CURRENT_SOURCE_DIR}/ggwave.h        "
  },
  {
    "path": "examples/esp32-rx/README.md",
    "chars": 1562,
    "preview": "# esp32-rx\n\nThis is a sample project for receiving audio data using [ESP32](https://www.espressif.com/en/products/socs/e"
  },
  {
    "path": "examples/esp32-rx/esp32-rx.ino",
    "chars": 13968,
    "preview": "// esp32-rx\n//\n// Sample sketch for receiving sound data using \"ggwave\"\n//\n// Tested MCU boards:\n//   - NodeMCU-ESP32-S\n"
  },
  {
    "path": "examples/ggwave-cli/CMakeLists.txt",
    "chars": 251,
    "preview": "add_executable(ggwave-cli main.cpp)\n\ntarget_include_directories(ggwave-cli PRIVATE\n    ..\n    ${SDL2_INCLUDE_DIRS}\n    )"
  },
  {
    "path": "examples/ggwave-cli/README.md",
    "chars": 129,
    "preview": "# ggwave-cli\n\nA basic command line tool for sending and receiving `ggwave` data.\n\n![ggwave-cli](https://i.imgur.com/fhNg"
  },
  {
    "path": "examples/ggwave-cli/main.cpp",
    "chars": 3537,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include \"ggwave-common.h\"\n#include \"ggwave-common-sdl2.h\"\n\n#include <SDL.h>\n\n#include <cstd"
  },
  {
    "path": "examples/ggwave-common-sdl2.cpp",
    "chars": 10782,
    "preview": "#include \"ggwave-common-sdl2.h\"\n\n#include \"ggwave-common.h\"\n\n#include \"ggwave/ggwave.h\"\n\n#include <SDL.h>\n#include <SDL_"
  },
  {
    "path": "examples/ggwave-common-sdl2.h",
    "chars": 423,
    "preview": "#pragma once\n\n#include <string>\n#include <memory>\n\nclass GGWave;\n\n// GGWave helpers\n\nvoid GGWave_setDefaultCaptureDevice"
  },
  {
    "path": "examples/ggwave-common.cpp",
    "chars": 1720,
    "preview": "#include \"ggwave-common.h\"\n\n#if !defined(_WIN32)\n#include <dlfcn.h>\n#include <unistd.h>\n#endif\n\n#include <cstring>\n#incl"
  },
  {
    "path": "examples/ggwave-common.h",
    "chars": 472,
    "preview": "#pragma once\n\n#include <chrono>\n#include <string>\n#include <map>\n#include <vector>\n\n// some basic helper methods for the"
  },
  {
    "path": "examples/ggwave-from-file/CMakeLists.txt",
    "chars": 282,
    "preview": "set(TARGET ggwave-from-file)\n\nadd_executable(${TARGET} main.cpp)\n\ntarget_include_directories(${TARGET} PRIVATE\n    ..\n  "
  },
  {
    "path": "examples/ggwave-from-file/README.md",
    "chars": 925,
    "preview": "## ggwave-from-file\n\nDecode GGWave messages from an input WAV file\n\n```\nUsage: ./bin/ggwave-from-file [-lN] [-d]\n    -lN"
  },
  {
    "path": "examples/ggwave-from-file/main.cpp",
    "chars": 4239,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#define DR_WAV_IMPLEMENTATION\n#include \"dr_wav.h\"\n\n#include \"ggwave-common.h\"\n\n#include <cst"
  },
  {
    "path": "examples/ggwave-js/CMakeLists.txt",
    "chars": 280,
    "preview": "set(TARGET ggwave-js)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/index-tmpl.html       ${CMAKE_RUNTIME_OUTPUT_DIRECTORY"
  },
  {
    "path": "examples/ggwave-js/README.md",
    "chars": 56,
    "preview": "# ggwave-js\n\nLive demo: https://ggwave-js.ggerganov.com\n"
  },
  {
    "path": "examples/ggwave-js/index-tmpl.html",
    "chars": 7552,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <title>ggwave : javascript example</title>\n    </head>\n    <body>"
  },
  {
    "path": "examples/ggwave-py/README.md",
    "chars": 268,
    "preview": "## ggwave-py\n\nPython examples using the `ggwave` python package\n\n### Install\n\n```bash\npip install ggwave\n```\n\nSome of th"
  },
  {
    "path": "examples/ggwave-py/receive.py",
    "chars": 614,
    "preview": "import ggwave\nimport pyaudio\n\np = pyaudio.PyAudio()\n\nstream = p.open(format=pyaudio.paFloat32, channels=1, rate=48000, i"
  },
  {
    "path": "examples/ggwave-py/send.py",
    "chars": 417,
    "preview": "import ggwave\nimport pyaudio\n\np = pyaudio.PyAudio()\n\n# generate audio waveform for string \"hello python\"\nwaveform = ggwa"
  },
  {
    "path": "examples/ggwave-rx/CMakeLists.txt",
    "chars": 241,
    "preview": "set(TARGET ggwave-rx)\n\nadd_executable(${TARGET} main.cpp)\n\ntarget_include_directories(${TARGET} PRIVATE\n    ..\n    ${SDL"
  },
  {
    "path": "examples/ggwave-rx/main.cpp",
    "chars": 730,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include \"ggwave-common.h\"\n#include \"ggwave-common-sdl2.h\"\n\n#include <SDL.h>\n\n#include <cstd"
  },
  {
    "path": "examples/ggwave-to-file/CMakeLists.txt",
    "chars": 228,
    "preview": "set(TARGET ggwave-to-file)\n\nadd_executable(${TARGET} main.cpp)\n\ntarget_include_directories(${TARGET} PRIVATE\n    ..\n    "
  },
  {
    "path": "examples/ggwave-to-file/README.md",
    "chars": 3382,
    "preview": "## ggwave-to-file\n\nOutput a generated waveform to an uncompressed WAV file.\n\n```\nUsage: ./bin/ggwave-to-file [-vN] [-sN]"
  },
  {
    "path": "examples/ggwave-to-file/ggwave-to-file-local.py",
    "chars": 770,
    "preview": "import ggwave\nimport wave\nimport numpy as np\n\n# Parameters\nvolume_ = 20\nsample_rate_ = 48000\nfilename = \"output.wav\"\n\n# "
  },
  {
    "path": "examples/ggwave-to-file/ggwave-to-file.php",
    "chars": 1541,
    "preview": "<?php\n\n$cmd = \"ggwave-to-file\";\n\nif (isset($_GET['s'])) { $cmd .= \" -s\".intval($_GET['s']); }\nif (isset($_GET['v'])) { $"
  },
  {
    "path": "examples/ggwave-to-file/ggwave-to-file.py",
    "chars": 1120,
    "preview": "from typing import Dict, Union\nimport requests\nimport wave\n\ndef ggwave(message: str,\n           file: str,\n           pr"
  },
  {
    "path": "examples/ggwave-to-file/main.cpp",
    "chars": 4587,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#define DR_WAV_IMPLEMENTATION\n#include \"dr_wav.h\"\n\n#include \"ggwave-common.h\"\n\n#include <cst"
  },
  {
    "path": "examples/ggwave-wasm/CMakeLists.txt",
    "chars": 883,
    "preview": "set(TARGET ggwave-wasm)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/build_timestamp-tmpl.h ${CMAKE_RUNTIME_OUTPUT_DIRECT"
  },
  {
    "path": "examples/ggwave-wasm/build_timestamp-tmpl.h",
    "chars": 63,
    "preview": "static const char * BUILD_TIMESTAMP=\"@GIT_DATE@ (@GIT_SHA1@)\";\n"
  },
  {
    "path": "examples/ggwave-wasm/index-tmpl.html",
    "chars": 15494,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>ggwave : emscripten example"
  },
  {
    "path": "examples/ggwave-wasm/main.cpp",
    "chars": 410,
    "preview": "#include \"build_timestamp.h\"\n\n#include \"ggwave-common-sdl2.h\"\n\n#include \"emscripten/emscripten.h\"\n\nvoid update() {\n    G"
  },
  {
    "path": "examples/ggwave-wasm/main.js",
    "chars": 2037,
    "preview": "function transmitText(sText) {\n    var r = new Uint8Array(256);\n    for (var i = 0; i < sText.length; ++i) {\n        r[i"
  },
  {
    "path": "examples/ggwave-wasm/style.css",
    "chars": 6920,
    "preview": "body {\n    margin: 0; background-color: white;\n    -webkit-font-smoothing: subpixel-antialiased;\n    font-smoothing: sub"
  },
  {
    "path": "examples/icons_font_awesome.h",
    "chars": 40378,
    "preview": "// Generated by https://github.com/juliettef/IconFontCppHeaders script\n// GenerateIconFontCppHeaders.py for language C89"
  },
  {
    "path": "examples/pfd/COPYING",
    "chars": 466,
    "preview": "            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n                    Version 2, December 2004\n\n Copyright (C) 200"
  },
  {
    "path": "examples/pfd/pfd.h",
    "chars": 51732,
    "preview": "//\n//  Portable File Dialogs\n//\n//  Copyright © 2018—2020 Sam Hocevar <sam@hocevar.net>\n//\n//  This library is free soft"
  },
  {
    "path": "examples/r2t2/CMakeLists.txt",
    "chars": 1524,
    "preview": "#\n# r2t2\n\nset(TARGET r2t2)\n\nif (NOT EMSCRIPTEN)\n    add_executable(${TARGET}\n        main.cpp\n        )\n\n    target_incl"
  },
  {
    "path": "examples/r2t2/README.md",
    "chars": 2898,
    "preview": "# r2t2\n\nTransmit data with the PC speaker\n\n<a href=\"https://user-images.githubusercontent.com/1991296/115141782-cba9f480"
  },
  {
    "path": "examples/r2t2/build_timestamp-tmpl.h",
    "chars": 63,
    "preview": "static const char * BUILD_TIMESTAMP=\"@GIT_DATE@ (@GIT_SHA1@)\";\n"
  },
  {
    "path": "examples/r2t2/index-tmpl.html",
    "chars": 8391,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>r2t2</title>\n\n        <meta"
  },
  {
    "path": "examples/r2t2/main.cpp",
    "chars": 4607,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include \"ggwave-common.h\"\n\n#include <fcntl.h>\n#include <unistd.h>\n#include <sys/ioctl.h>\n#i"
  },
  {
    "path": "examples/r2t2/main.js",
    "chars": 2037,
    "preview": "function transmitText(sText) {\n    var r = new Uint8Array(256);\n    for (var i = 0; i < sText.length; ++i) {\n        r[i"
  },
  {
    "path": "examples/r2t2/r2t2-rx.cpp",
    "chars": 13030,
    "preview": "#include \"ggwave-common.h\"\n\n#include \"ggwave/ggwave.h\"\n\n#ifdef __EMSCRIPTEN__\n#include \"build_timestamp.h\"\n#include <ems"
  },
  {
    "path": "examples/r2t2/style.css",
    "chars": 6919,
    "preview": "body {\n    margin: 0; background-color: white;\n    -webkit-font-smoothing: subpixel-antialiased;\n    font-smoothing: sub"
  },
  {
    "path": "examples/rp2040-rx/CMakeLists.txt",
    "chars": 14,
    "preview": "#\n# rp2040-rx\n"
  },
  {
    "path": "examples/rp2040-rx/README.md",
    "chars": 802,
    "preview": "# rp2040-rx\n\nThis is a sample project for receiving audio data using [RP2040](https://www.espressif.com/en/products/socs"
  },
  {
    "path": "examples/rp2040-rx/mic-analog.cpp",
    "chars": 5948,
    "preview": "/*\n * Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.\n *\n * SPDX-License-Identifier: Apache-2.0\n *"
  },
  {
    "path": "examples/rp2040-rx/mic-analog.h",
    "chars": 768,
    "preview": "/*\n * Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.\n *\n * SPDX-License-Identifier: Apache-2.0\n *"
  },
  {
    "path": "examples/rp2040-rx/rp2040-rx.ino",
    "chars": 8200,
    "preview": "// rp2040-rx\n//\n// Sample sketch for receiving sound data using \"ggwave\"\n//\n// Tested MCU boards:\n//   - Raspberry Pi Pi"
  },
  {
    "path": "examples/spectrogram/CMakeLists.txt",
    "chars": 1309,
    "preview": "set(TARGET spectrogram)\n\nif (EMSCRIPTEN)\n    add_executable(${TARGET} main.cpp)\n\n    target_include_directories(${TARGET"
  },
  {
    "path": "examples/spectrogram/README.md",
    "chars": 209,
    "preview": "# spectrogram\n\nReal-time audio spectrum visualizer\n\nWASM port: https://spectrogram.ggerganov.com\n\n![image](https://user-"
  },
  {
    "path": "examples/spectrogram/build_timestamp-tmpl.h",
    "chars": 63,
    "preview": "static const char * BUILD_TIMESTAMP=\"@GIT_DATE@ (@GIT_SHA1@)\";\n"
  },
  {
    "path": "examples/spectrogram/index-tmpl.html",
    "chars": 10806,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>Spectrogram</title>\n\n      "
  },
  {
    "path": "examples/spectrogram/main.cpp",
    "chars": 22227,
    "preview": "#include \"ggwave/ggwave.h\"\n#include \"ggwave-common.h\"\n\n#ifdef __EMSCRIPTEN__\n#include \"build_timestamp.h\"\n#include \"emsc"
  },
  {
    "path": "examples/spectrogram/style.css",
    "chars": 7932,
    "preview": "body {\n    margin: 0; background-color: black;\n    -webkit-font-smoothing: subpixel-antialiased;\n    font-smoothing: sub"
  },
  {
    "path": "examples/third-party/CMakeLists.txt",
    "chars": 78,
    "preview": "if (NOT EMSCRIPTEN)\nendif()\n\nadd_subdirectory(imgui)\nadd_subdirectory(ggsock)\n"
  },
  {
    "path": "examples/third-party/imgui/CMakeLists.txt",
    "chars": 3307,
    "preview": "if (GGWAVE_ALL_WARNINGS_3RD_PARTY)\n    if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n        set"
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl.cpp",
    "chars": 4299,
    "preview": "#include \"imgui-extra/imgui_impl.h\"\n\n#include \"imgui-extra/imgui_impl_sdl.h\"\n#include \"imgui-extra/imgui_impl_opengl3.h\""
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl.h",
    "chars": 841,
    "preview": "/*! \\file imgui_impl.h\n *  \\brief Enter description here.\n */\n\n#pragma once\n\n#if (defined(__EMSCRIPTEN__))\n#define IMGUI"
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl_opengl3.cpp",
    "chars": 33390,
    "preview": "// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline\n// - Desktop GL: 2.x 3.x 4.x\n// - Embedde"
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl_opengl3.h",
    "chars": 3629,
    "preview": "// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline\n// - Desktop GL: 2.x 3.x 4.x\n// - Embedde"
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl_sdl.cpp",
    "chars": 19424,
    "preview": "// dear imgui: Platform Binding for SDL2\n// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan"
  },
  {
    "path": "examples/third-party/imgui/imgui-extra/imgui_impl_sdl.h",
    "chars": 1832,
    "preview": "// dear imgui: Platform Binding for SDL2\n// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan"
  },
  {
    "path": "examples/waver/CMakeLists.txt",
    "chars": 1796,
    "preview": "set(TARGET waver)\n\nif (EMSCRIPTEN)\n    add_executable(${TARGET} main.cpp common.cpp interface.cpp interface-emscripten.c"
  },
  {
    "path": "examples/waver/README.md",
    "chars": 3630,
    "preview": "# Waver\n\nWaver allows you to send and receive text messages from nearby devices through sound waves.\n\nThis application c"
  },
  {
    "path": "examples/waver/build_timestamp-tmpl.h",
    "chars": 63,
    "preview": "static const char * BUILD_TIMESTAMP=\"@GIT_DATE@ (@GIT_SHA1@)\";\n"
  },
  {
    "path": "examples/waver/common.cpp",
    "chars": 87465,
    "preview": "#include \"common.h\"\n\n#include \"ggwave-common.h\"\n\n#include \"ggwave/ggwave.h\"\n\n#include \"ggsock/communicator.h\"\n#include \""
  },
  {
    "path": "examples/waver/common.h",
    "chars": 1270,
    "preview": "#pragma once\n\n#include \"ggwave-common-sdl2.h\"\n\n#include <thread>\n#include <vector>\n\nstd::thread initMainAndRunCore();\n\nv"
  },
  {
    "path": "examples/waver/index-tmpl.html",
    "chars": 10782,
    "preview": "<!doctype html>\n<html lang=\"en-us\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>Waver</title>\n\n        <met"
  },
  {
    "path": "examples/waver/interface-emscripten.cpp",
    "chars": 679,
    "preview": "#include \"interface.h\"\n\n#include <fstream>\n\nvoid interface_addFile(\n        const char * ,\n        const char * ,\n      "
  },
  {
    "path": "examples/waver/interface-unix.cpp",
    "chars": 1189,
    "preview": "#include \"interface.h\"\n\n#include \"pfd/pfd.h\"\n\n#include <fstream>\n\nvoid interface_addFile(\n        const char * ,\n       "
  },
  {
    "path": "examples/waver/interface.cpp",
    "chars": 2033,
    "preview": "#include \"interface.h\"\n\nint g_lastShareId = 0;\nint g_lastOpenId = 0;\nint g_lastDeleteId = 0;\nint g_lastReceivedId = 0;\ni"
  },
  {
    "path": "examples/waver/interface.h",
    "chars": 900,
    "preview": "#ifndef interface_h\n#define interface_h\n\n#ifdef __cplusplus\n#include \"common.h\"\n\nextern \"C\" {\n#endif\n\nvoid interface_add"
  },
  {
    "path": "examples/waver/main.cpp",
    "chars": 11780,
    "preview": "#include \"interface.h\"\n\n#include \"ggwave-common.h\"\n\n#ifdef __EMSCRIPTEN__\n#include \"build_timestamp.h\"\n#include \"emscrip"
  },
  {
    "path": "examples/waver/style.css",
    "chars": 7979,
    "preview": "body {\n    background-image: url('background-0.png');\n    margin: 0; background-color: white;\n    -webkit-font-smoothing"
  },
  {
    "path": "include/ggwave/ggwave.h",
    "chars": 35733,
    "preview": "#ifndef GGWAVE_H\n#define GGWAVE_H\n\n#ifdef GGWAVE_SHARED\n#    ifdef _WIN32\n#        ifdef GGWAVE_BUILD\n#            defin"
  },
  {
    "path": "media/favicons-waver/browserconfig.xml",
    "chars": 281,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig><msapplication><tile><square70x70logo src=\"/ms-icon-70x70.png\"/><s"
  },
  {
    "path": "media/favicons-waver/manifest.json",
    "chars": 720,
    "preview": "{\n \"name\": \"App\",\n \"icons\": [\n  {\n   \"src\": \"\\/android-icon-36x36.png\",\n   \"sizes\": \"36x36\",\n   \"type\": \"image\\/png\",\n  "
  },
  {
    "path": "snap/snapcraft.yaml",
    "chars": 3134,
    "preview": "\n  name: waver\n  version: '1.5.2'\n  summary: Data over sound\n  description: |\n    Waver allows you to send and receive t"
  },
  {
    "path": "src/CMakeLists.txt",
    "chars": 585,
    "preview": "# core\n\nset(TARGET ggwave)\n\nadd_library(${TARGET}\n    ggwave.cpp\n    )\n\ntarget_include_directories(${TARGET} PUBLIC\n    "
  },
  {
    "path": "src/fft.h",
    "chars": 20871,
    "preview": "#pragma once\n\n/*\n\nThe FFT routines below are taken from:\n\nhttps://www.kurims.kyoto-u.ac.jp/~ooura/fft.html\n\nLicense\nCopy"
  },
  {
    "path": "src/ggwave.cpp",
    "chars": 71470,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#if !defined(ARDUINO) && !defined(PROGMEM)\n#define PROGMEM\n#endif\n\n#include \"fft.h\"\n#include"
  },
  {
    "path": "src/reed-solomon/LICENSE",
    "chars": 1092,
    "preview": "Copyright © 2015 Mike Lubinets, github.com/mersinvald\n\nPermission is hereby granted, free of charge, to any person \nobta"
  },
  {
    "path": "src/reed-solomon/gf.hpp",
    "chars": 10141,
    "preview": "/* Author: Mike Lubinets (aka mersinvald)\r\n * Date: 29.12.15\r\n *\r\n * See LICENSE */\r\n\r\n#ifndef GF_H\r\n#define GF_H\r\n\r\n#in"
  },
  {
    "path": "src/reed-solomon/poly.hpp",
    "chars": 2371,
    "preview": "/* Author: Mike Lubinets (aka mersinvald)\r\n * Date: 29.12.15\r\n *\r\n * See LICENSE */\r\n\r\n#ifndef POLY_H\r\n#define POLY_H\r\n\r"
  },
  {
    "path": "src/reed-solomon/rs.hpp",
    "chars": 18005,
    "preview": "/* Author: Mike Lubinets (aka mersinvald)\r\n * Date: 29.12.15\r\n *\r\n * See LICENSE */\r\n\r\n#ifndef RS_HPP\r\n#define RS_HPP\r\n\r"
  },
  {
    "path": "tests/CMakeLists.txt",
    "chars": 1078,
    "preview": "if (EMSCRIPTEN)\n    #\n    # test-ggwave-js\n\n    set(TEST_TARGET test-ggwave-js)\n\n    add_test(NAME ${TEST_TARGET}\n      "
  },
  {
    "path": "tests/test-ggwave.c",
    "chars": 2253,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define CHECK(cond) \\\n    if (!("
  },
  {
    "path": "tests/test-ggwave.cpp",
    "chars": 15427,
    "preview": "#include \"ggwave/ggwave.h\"\n\n#include <cstring>\n#include <limits>\n#include <string>\n#include <typeinfo>\n#include <typeind"
  },
  {
    "path": "tests/test-ggwave.js",
    "chars": 738,
    "preview": "var factory = require('../bindings/javascript/ggwave.js')\n\nfactory().then(function(ggwave) {\n    // create ggwave instan"
  },
  {
    "path": "tests/test-ggwave.py",
    "chars": 952,
    "preview": "import sys\nimport ggwave\n\n# optionally disable logging\n#ggwave.disableLog()\n\n# create ggwave instance with default param"
  }
]

// ... and 4 more files (download for full content)

About this extraction

This page contains the full source code of the ggerganov/ggwave GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 154 files (1.2 MB), approximately 382.5k tokens, and a symbol index with 570 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!