alexokita

Ribbit Radio

Version Status C++ JavaScript WebAssembly Emscripten Web Audio API PWA

A WebAssembly-based digital radio communication application supporting real-time messaging over audio signals. Ribbit uses advanced DSP (Digital Signal Processing) algorithms to encode/decode messages into audio waveforms suitable for transmission via radio, speakers, or any audio medium.

Current Project Status

Version: 0.1.2 (Development) Status: Production-ready core functionality with active development on advanced features

βœ… Completed Features

🚧 In Progress / Planned Features

Project Structure

.
β”œβ”€β”€ build.bat              # Windows build script (auto-installs Emscripten)
β”œβ”€β”€ run_tests.bat          # Windows test server launcher
β”œβ”€β”€ run_tests.sh           # Linux/Mac test server launcher
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ Docs/                  # Comprehensive documentation
β”œβ”€β”€ Docs/                  # Comprehensive documentation
β”‚   β”œβ”€β”€ codec.md             # Codec & Message Architecture
β”‚   β”œβ”€β”€ quick_start.md       # Quick Start Guide
β”‚   β”œβ”€β”€ ribbit_wasm.md       # WASM Implementation Details
β”‚   └── ...
β”œβ”€β”€ web/                   # Web assets served to clients
β”‚   β”œβ”€β”€ index.html         # Main application (v0.1.2)
β”‚   β”œβ”€β”€ messageCodec.html  # Visual message encoder/decoder
β”‚   β”œβ”€β”€ headerCodec.html   # Header field codec
β”‚   β”œβ”€β”€ wasm_tests.html    # Test suite interface
β”‚   β”œβ”€β”€ decoder_tests.html # Live microphone testing & WAV generator
β”‚   β”œβ”€β”€ settings-page.html # Settings interface
β”‚   β”œβ”€β”€ ribbit.webmanifest # PWA manifest
β”‚   β”œβ”€β”€ sw.js              # Service worker (offline support)
β”‚   β”œβ”€β”€ scripts/           # JavaScript modules
β”‚   β”‚   β”œβ”€β”€ ribbit.js      # Emscripten WASM wrapper
β”‚   β”‚   β”œβ”€β”€ ribbit.wasm    # Compiled WebAssembly binary (~103KB)
β”‚   β”‚   β”œβ”€β”€ ribbit-wasm.js # Friendly WASM API wrapper
β”‚   β”‚   β”œβ”€β”€ index.js        # Main application logic
β”‚   β”‚   β”œβ”€β”€ message_format.js # Message format handler
β”‚   β”‚   β”œβ”€β”€ messageCodec.js # Message encoding/decoding API
β”‚   β”‚   β”œβ”€β”€ decoder_tests.js # Live testing implementation
β”‚   β”‚   β”œβ”€β”€ wasm_tests.js   # Test suite
β”‚   β”‚   β”œβ”€β”€ wav.js          # WAV file utilities
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ styles/            # CSS stylesheets
β”‚   β”œβ”€β”€ assets/            # Icons and images
β”‚   └── test/              # Test files
β”‚       β”œβ”€β”€ test-e2e/      # End-to-end tests (Playwright)
β”‚       └── setup.js       # Test configuration
└── src/                   # C++ source code
    └── ribbit/
        β”œβ”€β”€ src/
        β”‚   β”œβ”€β”€ ribbit.cc           # Main WASM bindings
        β”‚   β”œβ”€β”€ message_format.cc   # Message packing/unpacking
        β”‚   β”œβ”€β”€ decode.cc           # Decoder implementation
        β”‚   └── dsp/                # Digital Signal Processing library
        β”‚       β”œβ”€β”€ encoder.hh     # Signal encoder
        β”‚       β”œβ”€β”€ decoder.hh     # Signal decoder
        β”‚       β”œβ”€β”€ polar_*.hh     # Polar codes (error correction)
        β”‚       └── ... (60+ DSP headers)
        └── include/
            └── message_format.hh  # Message format definitions

Building

Prerequisites

Quick Build (Windows)

  1. Open Command Prompt or PowerShell
  2. Navigate to the project directory
  3. Run the build script:

    .\build.bat
    

The script will:

Manual Emscripten Setup

If you prefer manual setup or are not using Windows, follow these steps:

  1. Clone Emscripten SDK:

    git clone https://github.com/emscripten-core/emsdk.git
    cd emsdk
    
  2. Install and activate latest version:

    ./emsdk install latest
    ./emsdk activate latest
    
  3. Set up environment variables:

    
    # On Windows (PowerShell)
    .\emsdk_env.ps1
    
    # On Windows (Command Prompt)
    .\emsdk_env.bat
    
    # On Linux/macOS
    source ./emsdk_env.sh
    
  4. Verify installation:

    emcc --version
    
  5. Manual compilation:

    emcc src/ribbit/src/ribbit.cc src/ribbit/src/message_format.cc -o web/scripts/ribbit.js ^
        -s WASM=1 ^
        -s EXPORTED_RUNTIME_METHODS=['ccall','cwrap','stringToUTF8','UTF8ToString','lengthBytesUTF8'] ^
        -s EXPORTED_FUNCTIONS=['_malloc','_free','_createEncoder','_destroyEncoder','_createDecoder','_destroyDecoder','_feed_pointer','_feed_length','_message_pointer','_message_length','_signal_pointer','_signal_length','_payload_pointer','_payload_length','_feedDecoder','_digestFeed','_initEncoder','_readEncoder','_pack_contest_message','_unpack_contest_message'] ^
        -I src/ribbit/include ^
        -std=c++17 ^
        -O3 ^
        -s ALLOW_MEMORY_GROWTH=1 ^
        -s INITIAL_MEMORY=16MB ^
        -s MAXIMUM_MEMORY=64MB ^
        -s STACK_SIZE=1MB ^
        -s MODULARIZE=1 ^
        -s EXPORT_ES6=0 ^
        -s ENVIRONMENT=web ^
        -s FILESYSTEM=0 ^
        -s ASSERTIONS=0 ^
        -s MALLOC=emmalloc ^
        -msimd128 ^
        --closure 0 ^
        -flto
    

    Note: The build includes both ribbit.cc and message_format.cc to support dual-mode messaging. The EXPORTED_RUNTIME_METHODS includes string conversion functions required for message format handling.

Build Optimization Features

The build script uses the following optimizations:

Setup and running locally

  1. Serve the app (WASM requires a real origin; file:// will not work):
    • Windows: run_tests.bat
    • Linux/Mac: ./run_tests.sh
    • Or from repo root: python3 -m http.server 8000 and open http://localhost:8000/web/ (HTTPS needed for microphone: use the scripts or https://localhost:8443 if configured).
  2. Main app: web/index.html β€” chat, encode/decode, settings. Use Settings β†’ Application β†’ Install App to add to home screen for offline use.

  3. WASM and tests:
  4. Decoder and encoder:
  5. Message format and header codec:

Development

Developer-Friendly WASM API

Ribbit now includes a modern, promise-based WASM API that makes integration simple:

// Import the friendly API
import { RibbitWASM } from './scripts/ribbit-wasm.js';

// One-line initialization
const ribbit = await RibbitWASM.load();

// Encode a message
const audioBuffer = await ribbit.encodeMessage("Hello World!", {
    callsign: "W1AW",
    gridsquare: "FN31pr",
    name: "John"
});

// Decode audio
const decoded = await ribbit.decodeAudio(audioBuffer);
console.log("Received:", decoded.text);

// Cleanup when done
ribbit.destroy();

Key Features:

See Docs/README_WASM_API.md for complete API documentation.

Testing

A comprehensive test suite is available to verify encoder/decoder functionality, including automated tests, live microphone testing, WAV file generation for cross-device validation, and end-to-end browser testing.

Quick Start

Windows:

run_tests.bat

Linux/Mac:

./run_tests.sh

Then open your browser to:

Test Features

Automated Testing:

Live Testing (decoder_tests.html):

End-to-End Testing:

Documentation:

🎨 Visual Tools & Demos

1. Visual Message Codec

URL: http://localhost:8000/web/messageCodec.html ⭐

Interactive encoder/decoder that shows:

2. Message Format Demo (WASM Verification)

URL: http://localhost:8000/web/message_format_demo.html 🐸

A complete end-to-end demo of the Ribbit message format using the actual WebAssembly binary.

3. Decoder Tests & Live Testing

URL: https://localhost:8443/decoder_tests.html 🎀

Complete testing environment with:

[!NOTE] All tools require a local HTTP server to run (due to WASM security restrictions). Run: python3 -m http.server 8000 or use the provided test scripts.

Quick Start: Docs/quick_start.md Details: Docs/codec.md

Message Formats

Ribbit now supports dual-mode messaging:

Chat Mode (Type 1) πŸ’¬

Contest Mode (Type 2) πŸ†

Example Savings: β€œHello from Ribbit!” is 37% smaller in Contest mode (52 β†’ 33 bytes)

Full Details: Docs/ribbit_wasm.md

Known Issues & Bugs

πŸ› Confirmed Bugs

  1. Service Worker Cache Versioning
    • Location: web/sw.js
    • Issue: Cache version 'ribbit-cache-v1' is hardcoded and may not invalidate old caches
    • Impact: Users may see stale versions after updates
    • Status: Should implement cache versioning strategy
    • Severity: Low (affects updates)
  2. Audio Context State Management
    • Location: web/scripts/index.js - RibbitApp class
    • Issue: Audio context suspension/resumption could be more robust
    • Impact: Occasional audio playback issues on mobile browsers
    • Status: Improved with user interaction handlers, but edge cases may exist
    • Severity: Low (rare edge cases)

⚠️ Potential Issues

  1. Audio Buffer Size Mismatch
    • Web Audio API provides power-of-2 buffer sizes (e.g., 2048), decoder expects 160-sample chunks
    • Current implementation handles this with overflow buffer in digestFeedOptimized()
    • Recommendation: Add unit tests for various buffer sizes
  2. Concurrent Encode/Decode
    • No explicit locking mechanism if encoder and decoder run simultaneously
    • Current implementation suspends listening during transmission
    • Recommendation: Add state checks or queue system for edge cases
  3. Large Message Handling
    • Messages near 256-byte limit may not be validated early enough
    • Recommendation: Add pre-encoding length validation
  4. IndexedDB Error Handling
    • Some edge cases in database initialization may not be fully handled
    • Recommendation: Add more comprehensive error recovery

Optimization Opportunities

πŸš€ Performance Optimizations

  1. Web Workers for Audio Processing (High Priority)
    • Move audio processing to Web Worker to prevent UI blocking
    • Expected Impact: Smoother UI, better real-time performance
    • Complexity: Medium
    • Files to Modify: web/scripts/index.js, create web/scripts/audio-worker.js
  2. Lazy WASM Loading (Medium Priority)
    • Load WASM module only when needed, not on page load
    • Expected Impact: Faster initial page load, reduced memory usage
    • Complexity: Low
    • Files to Modify: web/scripts/index.js
    • Note: Already partially implemented with RibbitWASM.load()
  3. Message Queuing/Batching (Medium Priority)
    • Queue multiple messages for batch processing
    • Expected Impact: Better throughput for rapid message sending
    • Complexity: Medium
    • Files to Modify: web/scripts/index.js, web/scripts/messages.js
  4. Optimize Bit Manipulation (Low Priority)
    • Current bit manipulation in message_format.cc uses loops
    • Could use SIMD operations or lookup tables for common operations
    • Expected Impact: 10-20% faster encoding/decoding
    • Complexity: High
    • Files to Modify: src/ribbit/src/message_format.cc
  5. Memory Pooling (Low Priority)
    • Reuse buffers instead of allocating/deallocating for each message
    • Expected Impact: Reduced GC pressure, faster message processing
    • Complexity: Medium
    • Files to Modify: web/scripts/ribbit-wasm.js, src/ribbit/src/ribbit.cc
    • Note: Partially implemented in digestFeedOptimized()

πŸ’Ύ Memory Optimizations

  1. Reduce Static Buffer Sizes (If possible)
    • Current buffers: FEED_LENGTH=2048, SIGNAL_LENGTH=16384, PAYLOAD_LENGTH=256
    • Evaluate if sizes can be reduced without affecting functionality
    • Expected Impact: Lower memory footprint
    • Complexity: Medium (requires performance testing)
  2. Cleanup Unused WASM Memory
    • Explicitly free temporary buffers after use
    • Expected Impact: Lower peak memory usage
    • Complexity: Low
    • Files to Modify: web/scripts/ribbit-wasm.js
    • Status: Already implemented in RibbitWASM class

πŸ“¦ Bundle Size Optimizations

  1. WASM Size Reduction
    • Current WASM: ~103KB
    • Investigate removing unused DSP functions if not needed
    • Expected Impact: Smaller download, faster loading
    • Complexity: High (requires careful dependency analysis)
  2. Code Splitting
    • Separate contest mode codec into separate module
    • Expected Impact: Faster initial load if contest mode not needed
    • Complexity: Medium

πŸ”§ Code Quality Improvements

  1. TypeScript Migration (Long-term)
    • Add type safety to JavaScript codebase
    • Expected Impact: Fewer runtime errors, better IDE support
    • Complexity: High
    • Note: TypeScript definitions already exist for WASM API (ribbit-wasm.d.ts)
  2. Unit Test Coverage
    • Increase test coverage beyond integration tests
    • Add tests for edge cases, error conditions
    • Expected Impact: Higher code reliability
    • Complexity: Medium
    • Status: Test infrastructure in place with Jest and Playwright
  3. Error Recovery
    • Add automatic retry for failed decode operations
    • Expected Impact: Better resilience to noisy signals
    • Complexity: Medium
    • Status: Smart debouncing already implemented

Next Steps & Roadmap

Immediate (Next Sprint)

  1. Enhanced Error Handling
    • Improve decode error messages with more context
    • Add retry logic for transient failures
    • Better validation feedback in UI
  2. Contest Mode UI Integration
    • Add mode selector to main application
    • Integrate contest mode encoding/decoding in index.js
    • Add UI for contest mode message fields (timestamp, flags, etc.)
  3. Performance Monitoring
    • Add real-time performance metrics display
    • Track encoding/decoding times
    • Monitor memory usage patterns

Short-term (Next Month)

  1. ACK Array Implementation
    • Design ACK array structure (room for 20+ ACKs)
    • Implement packing/unpacking logic
    • Add UI for ACK management
  2. Statistics Dashboard
    • Message counts, success rates
    • Encoding/decoding performance metrics
    • Bandwidth usage statistics
    • Signal quality indicators
  3. Web Workers for Audio
    • Offload audio processing to Web Worker
    • Improve UI responsiveness
    • Better handling of concurrent operations
  4. Enhanced Testing
    • Expand E2E test coverage
    • Add performance regression tests
    • Cross-browser automated testing

Long-term (Next Quarter)

  1. ADIF/Cabrillo Logging
    • Export contact logs in standard formats
    • Import from existing log files
    • Integration with popular logging software
  2. QSO Mode
    • Automatic contact logging
    • Duplicate detection
    • Contest logging features
    • Real-time QSO tracking
  3. Performance Monitoring
    • Real-time performance metrics
    • Bottleneck identification
    • Performance profiling tools
    • Automated performance testing
  4. Advanced Features
    • Message compression
    • Multiple modulation schemes
    • Adaptive data rates
    • Optional encryption layer

Contact Logging

Saving and exporting contacts:

AI Agent & Developer Guidance

This project has specific constraints to ensure offline reliability and portability. Please read the AgentGuidance before writing code.

Contributing

When reporting bugs or implementing optimizations:

  1. Bug Reports: Include reproduction steps, expected vs actual behavior, browser/OS info
  2. Optimizations: Include performance benchmarks before/after, explain trade-offs
  3. Code Changes: Follow existing code style, add tests for new features
  4. Documentation: Update relevant docs when adding features

Resources & Documentation

Deployment (GitHub Pages)

This repo is set up as a GitHub Pages site (e.g. https://<user>.github.io/badkangaroo.github.io/ or your custom domain). A GitHub Action deploys the web folder when you push to the release branch or when you push a release tag (e.g. v0.1.2).