Skip to content
igtothPublic

About

No description, website, or topics provided.

Resources

Stars

53 stars

Watchers

2 watching

Forks

Repository files navigation

Sidetone

Sidetone

A SIP softphone built for troubleshooting: place the call, see the ladder, and know why it failed.
Test calls over UDP, TCP, TLS or WebRTC, SRTP included, pcap and pcapng analysis, RTP quality and MOS, plain-language diagnostics,
an AI second opinion with your own keys, automated test suites and an MCP server, for Windows, macOS, Linux and the browser.

Written in Rust Windows, macOS, Linux and the browser License: MIT Status: alpha MCP server CI

Download · Open it in the browser · Test suite examples · Contribute

Alpha: expect rough edges. A capture that Sidetone reads wrong or a finding that misleads? Open an issue with a redacted pcapng (Export › Redacted pcapng): real traces are what improve the rules most.


Sidetone on the desktop: the phone panel on the left with account Lab 2001 registered, the toolbar with Conference active, the keypad, BLF lamps showing 3001 busy and 5001 free, and three connected lines, two of them joined in a conference; on the right the current call with Opus as codec, media addresses and RTP counters, the phone event log ending in conference: lines 4 and 6 joined, and the call history with 404 and 486 results
Three lines, two of them in a local conference, Opus on the wire, BLF lamps, every event and result in plain words.

Features · Everything in the box · Automation · AI · Under the hood · Get started · Help wanted · Downloads


A real softphone

Several accounts and lines, hold, mute, blind and attended transfer, DTMF three ways, DND and auto answer, call forwarding, a voicemail lamp, SIP MESSAGE, microphone and speaker. SIP over UDP, TCP or TLS from the desktop, with SDES or DTLS-SRTP, or over WebSocket with WebRTC from the browser.

It explains the call

Around 40 deterministic rules read signaling and media and say what went wrong in words: missing ACK, NAT in SDP, one-way audio, codec mismatch, loss and jitter, with the message numbers as evidence.

Evidence you can share

Annotated pcapng with findings as Wireshark packet comments, TLS keys embedded when available, and a redacted export that masks numbers, names, credentials and public IPs.

Built for troubleshooting

A live SIP trace, every packet captured without a driver, DNS SRV and NAT checks, and a CLI, JSON test suites and an MCP server so scripts and AI agents can do the same.

Features

Every screenshot is Sidetone itself, captured headless by scripts/readme-shots.mjs against the throwaway PBX in lab/ and the built-in sample captures, with a test tone instead of a microphone. Some are in the dark theme (the Theme button, or your system setting).

Dark theme: the SIP trace page with a live list of messages (time, direction, address, first line coloured by result, Call-ID), filters to hide REGISTER and OPTIONS, Pause, Clear, Save pcapng and Analyze capture, and the selected INVITE shown in full below
The live SIP trace: every request and response as it happens.

See the wire while you talk

Each message the phone sends or receives appears at once with its time, direction and peer; responses are coloured by class. Filter by number, method or Call-ID, hide the REGISTER and OPTIONS noise, pause, save the session as pcapng, or open it in the analyzer with one click.
The analysis view of a capture with seven calls: the dialogs list on the left, the ladder of a NAT call with ten retransmitted 200 OK responses marked in red, and the Findings tab listing 200 OK retransmitted, No ACK and Call ended 32 s after answer
A remote worker behind NAT: 200 OK retransmitted ten times, no ACK, drop at 32 s.

The ladder, with the diagnosis on it

Calls you make are captured and analyzed with the same engine as any pcap or pcapng from Wireshark, tcpdump, sngrep or an SBC. Dialogs are grouped by Call-ID; the ladder marks retransmissions and colours each response class; a dot shows which messages a finding points to.
Dark theme: the INVITE selected in the ladder and, below, the two findings it triggered (private Contact and private SDP address) above the full SIP message with coloured header names
The INVITE that started it: private Contact and private SDP address.

About 40 rules that explain the call

Missing ACK, NAT in SDP, one-way audio, codec mismatch, failed authentication, glare, session timer expiry, loss and jitter: each finding says what happened in words, with the message numbers as evidence.
The Media tab for a call with two PCMU streams: packets, lost, loss 13.40 and 15.00 percent in red, jitter 46.4 ms, max gap 1513 ms and MOS estimates of 2.92 and 2.90
Both directions of a bad call: loss, jitter, a 1.5 s gap and MOS below 3.

Media you can measure

Each RTP stream is tied to its call through the SDP: codec, packets, loss, RFC 3550 jitter, the longest gap, ptime, RFC 4733 digits and an ITU-T G.107 E-model MOS estimate. Per-second charts show jitter, loss and MOS over the call with the SIP events marked; RTCP sender and receiver reports (RFC 3550), RTCP XR VoIP metrics (RFC 3611) and vq-rtcpxr PUBLISH reports (RFC 6035) add what the far end measured, including round trip time; G.711 streams also get level, silence and clipping. Calls of the same session on both sides of an SBC or B2BUA are linked by X-CID, Session-ID and similar headers. MOS is also worked out through a fixed 50 ms, a fixed 200 ms and an adaptive jitter buffer, where a packet that arrives too late counts as lost. HEP (Homer) packets in a capture are unwrapped, the phone can send a HEPv3 copy of every SIP message to a Homer collector, and SRTP calls can be saved with the media decrypted. The ladder can show time since the start, since the row above or as clock time, and fold retransmissions into the arrow they repeat.
Account settings on the Media tab: codecs in order of preference with Opus, PCMU and PCMA ticked, SRTP media encryption set to Optional, packet time and offered direction, and tabs for Account, Server and registration, Network, Media, DTMF, Advanced SIP, Headers and BLF
Per-account media: Opus and G.711 in your order, SRTP off, optional or required, with SDES or DTLS-SRTP keys.

Every knob a desk phone has, and a preview

Per account: UDP, TCP or TLS, outbound proxy, expiry and retry, keepalives, local IP and port, rport, symmetric RTP, RTP ports, DSCP, SDP address override, T1, codec order (Opus, PCMU, PCMA), SRTP, ptime, DTMF mode and payload type, session timers, user=phone, compact headers, PRACK, GRUU, long Contact, extra headers, BLF extensions, and a preview of the INVITE they produce. Some exist to reproduce a broken client on purpose, like skipping the ACK.
Dark theme: the Diagnostics page with an OPTIONS ping answered 200 OK in 4 ms by Asterisk, a DNS lookup showing where UDP requests go, the NAT card with STUN servers and what the SIP server sees for each account, and the Audio card with microphone and speaker choice, level meters and a loopback test
Reachability, DNS, NAT and audio checks in one place.

Diagnostics before the call

OPTIONS ping with round trip and server agent, RFC 3263 lookups (NAPTR, SRV for UDP, TCP and TLS, A/AAAA), STUN against two servers to spot a symmetric NAT, the address each registrar sees you from, a microphone and speaker test with level meters, and a live capture on any network interface for traffic that is not the phone's own.
Dark theme: a capture with one NAT call in Analysis, the ladder with retransmitted 200 OK responses, and the Ask AI tab showing the provider and model from Settings, a masking checkbox ticked, a question about a remote worker, and the masked prompt preview
Ask AI, with "Show what will be sent" before anything leaves.

An AI second opinion

An AI panel docked under any page lets you hold a conversation about the selected call, the live trace or a capture: the model gets the findings, the ladder, the RTP statistics and the relevant raw messages, masked by default. Configure it once in Settings, AI: Anthropic, any OpenAI-compatible service (OpenAI, Gemini, OpenRouter, Groq, Mistral, DeepSeek, LM Studio, vLLM) or a local Ollama, with a connection test.
The browser version registered over WebSocket as 4001, a call to 600 connected with Opus over DTLS-SRTP, live packet counters and the ICE path, the phone events and DTMF sent as RFC 4733
No install: the browser version on GitHub Pages, calling over WebRTC.

The same phone in the browser

On GitHub Pages Sidetone talks SIP over WebSocket (RFC 7118) with WebRTC audio, so it reaches any PBX or SBC with a WSS listener. Several lines with automatic hold and call waiting, mute, blind and attended transfer, a three-way conference mixed with Web Audio, and DTMF; analysis runs in the page through WebAssembly.
The interface in Portuguese (Brazil): the Help page with sections on getting started, making calls, hold and transfer, and TCP, TLS, SRTP, BLF and conference, and the language selector
The interface and the built-in help in Portuguese.

Your language, with help built in

English, Portuguese (Brazil), Spanish, German, French, Chinese (Simplified) and Hindi, switched in Settings or on the Help page. Findings and explanations are translated too; SIP messages and traces stay as they were on the wire, so what you paste into a ticket reads the same for everyone. Help covers accounts, calls, transfers, TCP/TLS, SRTP, BLF, conference, analysis and common problems.

Everything in the box

About 40 diagnostic rules

INVITE without response · failure codes explained · 200 OK retransmitted · no ACK · drop at 32 s · session timer expiry · credentials rejected · challenge not answered · 481 in dialog · glare · slow first response · post-dial delay · private SDP or Contact behind a public source · wrong interface on an unanswered REGISTER · no common codec · answer with codecs not offered · SRTP vs RTP · missing crypto or fingerprint · DTLS role conflict · DTMF not negotiated · ptime mismatch · hold · one-way audio · no RTP · asymmetric RTP · loss · jitter · gaps · SSRC change · unnegotiated payload types · low MOS · far-end loss, round trip and MOS from RTCP and vq-rtcpxr · phone boot provisioning (DHCP option 66/150 missing, TFTP file not found, no answer, cut off) · RTP that carries only silence · clipping · Q.850 Reason causes · missing mandatory headers · Content-Length errors · Max-Forwards near zero

Captures in and out

Capture live on any network interface (libpcap or Npcap, loaded at run time) with a BPF filter, watch SIP go by, then analyze or save it.

Read: pcap and pcapng (Ethernet, VLAN, Linux cooked v1 and v2, raw IP, loopback, Wireshark exported PDUs), IPv4 and IPv6, SIP over UDP, TCP and decrypted TLS, TLS key logs from pcapng.

Search: Wireshark-style display filters over SIP and SDP (ip.addr == 10.0.0.5 && sip.status >= 400, sdp.codec == PCMA, sip.from contains "2001") in the trace and in Analysis.

Listen: pick any RTP stream, hear it and see its waveform with a playhead (G.711 and Opus), save it as WAV.

Write: the phone's own traffic as it travelled (SIP over TCP as TCP, over TLS as decrypted exported PDUs, like Wireshark's Export PDUs); annotated pcapng with findings as packet comments and TLS keys kept; redacted pcapng for sharing; one call or the whole capture; ladder as SVG; report as JSON; stereo WAV of each test call (left sent, right received).

The phone

Several accounts with re-registration at 90% of the expiry and retry on failure · SIP over UDP, TCP and TLS (certificate check on or off per account) · SRTP with SDES keys or DTLS-SRTP (certificate checked against a=fingerprint), AES_CM_128_HMAC_SHA1_80 and _32 and AEAD_AES_128/256_GCM, optional or mandatory · digest auth (MD5, qop auth) · several lines with automatic hold · hold and resume by re-INVITE · mute · blind transfer (REFER) and attended transfer (REFER with Replaces), and being transferred · three-way conference mixed locally · BLF (SUBSCRIBE to the dialog event package) showing idle, ringing and busy, with presence (PIDF) when the server offers it, and your own presence published with PUBLISH · DTMF as RFC 4733, SIP INFO or inband tones, and received digits shown · DND and auto answer with the reject code you choose · intercom answer (Call-Info, Alert-Info) · PRACK, UPDATE, session timers, late offer · ringback and ring tones · per-call WAV recording · DNS SRV and outbound proxy · direct, unregistered calls to any SIP URI (anonymous From, for testing URI dialing) · dial strings with headers and post-answer DTMF (600?Subject=x,,123#) · 16 codecs, each tested against Asterisk: G.711 μ-law and A-law, G.722, Opus (16 kHz audio path, in-band FEC), G.729A, iLBC (20 and 30 ms), Speex narrowband and wideband, GSM 06.10, G.726-16/24/32/40 (RFC 3551 or AAL2 bit order), linear PCM at 8, 16 and 44.1 kHz; a global list in order of preference, a list per account and a list per call · configuration import and export as one JSON file (in the app and with sidetone config export|import), passwords optional, also loaded from an HTTP(S) provisioning URL · call forwarding (always, busy, no answer) with 302 · voicemail lamp from message-summary (RFC 3842) · SIP MESSAGE (RFC 3428) sent and received · HEPv3 copies of every SIP message to a Homer collector · live call table with duration, codec, transport, RTP counters and the result of the last action (hold, transfer or DTMF refused, unsupported or unanswered, with the reason) · phone-only mode that turns the desktop window into a compact softphone · interface in English, Portuguese (Brazil), Spanish, German, French, Chinese (Simplified) and Hindi, with built-in help · WebRTC with Opus, ICE and DTLS-SRTP in the browser, with several lines, attended transfer and conference

Command line

analyze · export · ai · call · answer · register · options · test · test-gen · test-format · samples · profile · serve · mcp

MCP tools

analyze_capture · get_ladder · get_message · get_call_context · export_pcapng · generate_sample · sip_options · test_call · get_test_suite_format · run_test_suite

Built-in examples

Seven synthetic captures with known problems, so every rule can be seen without real customer traffic: a clean call with DTMF, NAT with one-way audio and a 32 s drop, a 488 codec rejection, a lossy call, a REGISTER that never gets an answer, an SRTP mismatch, and all of them together.

Made to be automated

The CLI and the web app share one engine, so anything the window does, a script does too.

# Read a capture: calls, ladder, RTP, findings
sidetone analyze trace.pcapng --ladder
sidetone analyze trace.pcapng --call 3 --svg call3.svg
sidetone analyze trace.pcapng --json > report.json

# Share it: findings as Wireshark comments, or masked for a vendor ticket
sidetone export trace.pcapng -o annotated.pcapng
sidetone export trace.pcapng -o share.pcapng --call 3 --redact

# Be a Homer collector: receive HEPv3 from Kamailio, OpenSIPS, FreeSWITCH
# or heplify, save it, and analyze it like any capture
sidetone hep --listen 0.0.0.0:9060 -o hep.pcapng

# Place calls from a script, then read what happened
sidetone call 600 --domain pbx.lab:5060 --user 2001 --password "$PW" \
  --register --dtmf 123# --pcap call.pcapng --wav call.wav
sidetone answer --domain pbx.lab --user 3001 --password "$PW" --register --audio echo
sidetone options pbx.lab

Test suites are JSON: cases made of register, options, call, wait and unregister steps, each with expectations (final status, maximum errors, minimum MOS, loss, jitter, post-dial delay, talk time, codec, RTP received, rules that must or must not appear). Each case saves its pcapng.

SIP_PASSWORD=... sidetone test examples/asterisk-lab.suite.json --junit junit.xml
sidetone test suite.json --ai-explain     # failed cases get an AI explanation
sidetone test-gen "register 2001 on pbx.lab and check echo 600 with DTMF and MOS above 4" -o new.suite.json
{ "name": "echo test with DTMF",
  "steps": [ { "call": { "target": "600", "duration": 4, "dtmf": "123#",
      "expect": { "status": 200, "min_mos": 4.0, "rtp_received": true,
                  "rules_present": ["rtp.dtmf"], "rules_absent": ["rtp.one_way"] } } } ] }

Serve the analyzer and the phone to an AI agent over the Model Context Protocol:

{ "mcpServers": { "sidetone": { "command": "/path/to/sidetone", "args": ["mcp"] } } }

AI with your own keys

Sidetone has no AI of its own and no account. Detection is deterministic; the model is only asked to interpret, which keeps answers grounded and cheap. Pick Anthropic, any OpenAI-compatible endpoint (a gateway, LM Studio, vLLM) or a local Ollama; nothing is sent until you ask, masking is on by default, and "Show what will be sent" prints the exact prompt.

export ANTHROPIC_API_KEY=...
sidetone ai trace.pcapng --call 2 --lang "Portuguese (Brazil)"
sidetone ai trace.pcapng --provider ollama --model llama3.1
sidetone ai trace.pcapng --dry-run

In the browser the key stays in that browser and goes only to the provider; Ollama needs OLLAMA_ORIGINS to include the page origin.

Under the hood

  • Engine first: crates/sidetone-core holds capture I/O, SIP/SDP/RTP parsing, call correlation, the rules, the ladder, export, redaction and the AI prompt, with no network or audio code, so it runs natively and as WebAssembly.
  • One frontend, three homes: web/ runs on GitHub Pages with the analyzer in WASM, behind sidetone serve, and inside the Tauri desktop app, which starts the local server on a random loopback port protected by a per-launch token.
  • A phone engine, not a script: crates/sidetone-ua runs one signaling thread with RFC 3261 client transactions and timers, dialogs, re-INVITE, REFER/NOTIFY and Replaces, and a media thread pair per line; the UI drives it through a small HTTP API and reads snapshots, events and the trace. Accounts, settings and history live in your user configuration folder (SIDETONE_CONFIG_DIR overrides it).
  • Capture without drivers: the phone records its own datagrams with real addresses and timestamps, so no Npcap, libpcap or root is needed.
  • The interface the OS would use: the local address comes from the route to the server, so a VPN or virtual adapter does not end up in Via, Contact and SDP.
  • Tested against a real PBX: CI runs unit tests on Linux, Windows and macOS, builds the WASM, starts Asterisk from lab/, runs the example suite, drives the phone engine through calls, hold, DTMF, both kinds of transfer, DND and auto answer, and opens every exported capture with tshark.

Get started

git clone https://github.com/igtoth/sidetone
cd sidetone
cargo run --release -p sidetone-cli -- serve      # phone and analyzer on http://127.0.0.1:8640
cargo run --release -p sidetone-cli -- samples ./samples
cargo test --workspace --exclude sidetone-desktop

A recent stable Rust (CI uses stable). The desktop app builds with npx @tauri-apps/cli@2 build in app/; on Linux it needs WebKitGTK 4.1. For a local PBX to call: lab/run-asterisk.sh (Asterisk on UDP, TCP, TLS and WebSocket, with SDES and DTLS-SRTP users, a WebRTC user, BLF and presence hints, echo, busy and unallocated numbers).

Important

Status: alpha. The analyzer, the desktop and browser phones, test suites and the MCP server work and are covered by tests and a live PBX in CI, but Sidetone is young: expect rough edges with PBXs and SBCs the lab does not cover, and please report them. MOS is an estimate from one capture point, as any single-point measurement is.

Provisioning

Sidetone can load account settings from a small XML file served over HTTP(S). In Settings, open an account and press Provision, then paste the URL. A valid file is saved and the account registers. Besides its own strict format, the desktop app reads the Yealink .cfg, Polycom XML and Cisco SEP<MAC>.cnf.xml files a PBX already serves to desk phones (the first configured line becomes the account), over HTTP, HTTPS or TFTP, with {mac} in the URL filled with the device MAC. It can ask DHCP for the server phones are given (options 66, 150, 160), Diagnostics fetches what a phone with a given MAC would get, and Analysis explains DHCP and TFTP in a capture of a phone booting. Every key, the vendor mappings, the samples and the resync rules are in docs/provisioning.md. To back up or move the whole configuration instead, use Settings, Import and export (one JSON file, from a file or a URL).

Example (sidetone-provision version 1; display_name is required):

<?xml version="1.0" encoding="UTF-8"?>
<sidetone-provision version="1">
  <account.1.user>2001</account.1.user>
  <account.1.display_name>Lab 2001</account.1.display_name>
  <account.1.domain>pbx.example.com</account.1.domain>
  <account.1.password>secret</account.1.password>
  <account.1.transport>udp</account.1.transport>
</sidetone-provision>

Browser accounts also need account.1.ws and usually account.1.ice.

When the registrar sends SIP NOTIFY with Event: check-sync or Event: resync, Sidetone re-downloads the stored provisioning URL for that account. If Accept requests only from the registrar is on, check-sync applies only when the NOTIFY comes from the registrar. A resync during a call is deferred until that account's last call ends; if a new call starts while the file is downloading, apply waits again. Downloads for the same account are at least 10 seconds apart, measured from the start of the last attempt.

The desktop app fetches provisioning URLs directly (it does not use HTTPS_PROXY). TLS is checked against public roots unless you turn off Check the server's TLS certificate in the provision dialog; the browser phone always uses the browser's TLS rules and cannot disable verification. An HTTPS-hosted page cannot fetch an http:// provisioning URL (mixed content); use the desktop app for a LAN HTTP server.

In the browser, account.1.remember_password set to 0 keeps the password only until you reload the page (unless you save with remember enabled in Settings).

Help wanted

  • Try it on your own traces. A capture Sidetone reads wrong, or a finding that misleads, sent as a redacted pcapng in an issue, improves the rules more than anything else.
  • Write a rule. Each rule is a few lines in crates/sidetone-core/src/rules.rs plus a synthetic scenario in synth.rs that proves it.
  • Share a test suite for your PBX, SBC or carrier in examples/.
  • Package it for the system you use (Homebrew, winget, AUR, Flatpak).

Downloads

Each version gets a release with installers for every platform: take the latest release, or pick a file below (version 0.1.25).

Platform Install Portable (no install) Command line (also standalone)
Windows 10/11 (x64) Installer (.exe) · MSI Sidetone_0.1.25_x64_portable.zip sidetone-v0.1.25-x86_64-pc-windows-msvc.zip
macOS 11+ (Apple silicon) Sidetone_0.1.25_aarch64.dmg Sidetone_aarch64.app.tar.gz sidetone-v0.1.25-aarch64-apple-darwin.tar.gz
macOS 11+ (Intel) Sidetone_0.1.25_x64.dmg Sidetone_x64.app.tar.gz sidetone-v0.1.25-x86_64-apple-darwin.tar.gz
Linux (x86_64) .deb · .rpm AppImage sidetone-v0.1.25-x86_64-unknown-linux-gnu.tar.gz
Linux (arm64) sidetone-v0.1.25-aarch64-unknown-linux-gnu.tar.gz
Web no download: open it in the browser

Portable and standalone. Nothing has to be installed:

  • Windows: unzip Sidetone_..._portable.zip anywhere (a USB stick works) and run Sidetone.exe. It uses the WebView2 that comes with Windows 10 and 11.
  • macOS: unpack Sidetone_....app.tar.gz and open Sidetone.app from any folder.
  • Linux: chmod +x the AppImage and run it. On distributions without FUSE 2, run it with --appimage-extract-and-run.
  • Command line, any platform: a single executable with the interface built in. Double click sidetone (or run it with no arguments) and the full app opens in your browser, with no WebView or system library needed. Closing its window stops it. sidetone serve --open does the same from a terminal.

Settings, accounts and history live in your user configuration folder in every form, so you can switch between them. To keep everything with the program instead (a USB stick, say), create a folder named sidetone-data next to the executable, or set SIDETONE_CONFIG_DIR.

Install

Windows. Run the .exe installer (or the .msi for managed deployments). The downloads are not code-signed yet: if SmartScreen warns, choose More info › Run anyway. Allow Sidetone through Windows Firewall when asked, or incoming calls cannot reach it.

macOS. Open the .dmg and drag Sidetone to Applications. The app is not signed yet, so the first time right-click it and choose Open (or run xattr -dr com.apple.quarantine /Applications/Sidetone.app). macOS asks for microphone access on the first call.

Linux. Debian and Ubuntu: sudo apt install ./Sidetone_0.1.25_amd64.deb. Fedora and openSUSE: sudo dnf install ./Sidetone-0.1.25-1.x86_64.rpm. Anywhere else: chmod +x Sidetone_0.1.25_amd64.AppImage and run it. The desktop app needs WebKitGTK 4.1 (present on current distributions).

Command line. Unpack the archive and put sidetone on your PATH:

tar xzf sidetone-v0.1.25-x86_64-unknown-linux-gnu.tar.gz
sudo install sidetone-v0.1.25-x86_64-unknown-linux-gnu/sidetone /usr/local/bin/
sidetone              # the full app in your browser (same as sidetone serve --open)

On macOS remove the quarantine flag first (xattr -d com.apple.quarantine sidetone). The archive also has the example test suites.

Capturing other hosts' traffic (Diagnostics, Capture on an interface) needs a packet capture library and the right to use it. Windows: install Npcap (Wireshark installs it). macOS: libpcap is built in; install Wireshark's ChmodBPF or run as root. Linux: libpcap is usually installed; give the binary the capability once with sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/sidetone-desktop (or the sidetone CLI), or run it with sudo. Everything else works without it.

From source. See Get started.

Documentation

Where What it covers
docs/provisioning.md provisioning XML, samples, and SIP resync
sidetone --help, sidetone test-format every command and the test suite format
examples/ test suites, including one that fails on purpose
lab/ the Asterisk lab used by CI and the screenshots
crates/sidetone-core/src/rules.rs every rule and its explanation
crates/sidetone-core/src/synth.rs the sample scenarios
.github/workflows/ CI, releases and the GitHub Pages build

License and credits

Sidetone is licensed under the MIT License. Copyright © 2026 Ighor Toth.

Written by Ighor Toth with Claude Code, Anthropic's AI coding assistant, as co-author: commits it helped write carry a Co-Authored-By line.

Codecs: G.722 from libg722 (Steve Underwood, public domain, and CMU) through the ezk-g722 translation (MIT); G.726 from soundkit-g726 (MIT); GSM 06.10 from libgsm (Jutta Degener and Carsten Bormann, TU Berlin); Speex from libspeex (Xiph.Org, BSD) and iLBC from WebRTC (BSD), both bundled in crates/sidetone-ua/native with their licences; G.729 from the g729-sys crate, which describes itself as MIT but is a port of bcg729 (GPL-3.0): builds that must avoid GPL code can leave it out.

The interface uses IBM Plex Sans and IBM Plex Mono (SIL Open Font License), loaded from Google Fonts. Every capture in the screenshots and samples was made for Sidetone.

Sidetone is an independent open-source project, not affiliated with, sponsored by or endorsed by any other software vendor. Product names such as Wireshark and Asterisk belong to their owners and are used only to describe compatibility. The software is provided "as is", without warranty of any kind, as the license states.

About

No description, website, or topics provided.

Resources

Stars

53 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages