Skip to main content

🦜 Synthetic Voice Detection

Project description

Jabberjay 🦜

One API. Every state-of-the-art synthetic voice detector.

Jabberjay social preview

PyPI CI Python License: MIT Downloads Docs DOI GitHub Sponsors Ko-fi


Why Jabberjay?

Synthetic voice detection is a fragmented landscape — state-of-the-art models are scattered across research repositories, each with its own dependencies, input formats, and output conventions. Jabberjay brings them all under one consistent Python API and CLI so you can detect AI-generated speech without wrestling with model internals.

  • Seven model families — ViT, AST, Wav2Vec2, HuBERT, WavLM, RawNet2, and a classical baseline
  • Unified output — every model returns the same DetectionResult with label, confidence, and scores
  • Zero boilerplate — pass a file path, get a verdict; models are downloaded and cached automatically
  • Flexible — use strings for quick experiments, enums for IDE autocomplete, or pre-load audio to run multiple models on the same clip
$ jabberjay interview.wav
Bonafide ✔️  (94.1% confidence, model=VIT)

$ jabberjay suspicious.wav -m HuBERT
Spoof ❌  (97.8% confidence, model=HuBERT)

Installation

pip install jabberjay

Requires Python ≥ 3.10. Models are downloaded from Hugging Face Hub on first use and cached locally.


Quickstart

from Jabberjay import Jabberjay

jj = Jabberjay()
result = jj.detect("audio.wav")

print(result)              # Bonafide ✔️ (94.1% confidence, model=VIT)
print(result.label)        # "Bonafide"
print(result.is_bonafide)  # True
print(result.confidence)   # 0.941

Models

Vision Transformer (ViT)

Model Dataset Visualisation
MattyB95/VIT-ASVspoof2019-ConstantQ-Synthetic-Voice-Detection ASVspoof2019 ConstantQ
MattyB95/VIT-ASVspoof2019-Mel_Spectrogram-Synthetic-Voice-Detection ASVspoof2019 MelSpectrogram
MattyB95/VIT-ASVspoof2019-MFCC-Synthetic-Voice-Detection ASVspoof2019 MFCC
MattyB95/VIT-ASVspoof5-ConstantQ-Synthetic-Voice-Detection ASVspoof5 ConstantQ
MattyB95/VIT-ASVspoof5-Mel_Spectrogram-Synthetic-Voice-Detection ASVspoof5 MelSpectrogram
MattyB95/VIT-ASVspoof5-MFCC-Synthetic-Voice-Detection ASVspoof5 MFCC
MattyB95/VIT-VoxCelebSpoof-ConstantQ-Synthetic-Voice-Detection VoxCelebSpoof ConstantQ
MattyB95/VIT-VoxCelebSpoof-Mel_Spectrogram-Synthetic-Voice-Detection VoxCelebSpoof MelSpectrogram
MattyB95/VIT-VoxCelebSpoof-MFCC-Synthetic-Voice-Detection VoxCelebSpoof MFCC

Audio Spectrogram Transformer (AST)

Model Dataset
MattyB95/AST-ASVspoof2019-Synthetic-Voice-Detection ASVspoof2019
MattyB95/AST-ASVspoof5-Synthetic-Voice-Detection ASVspoof5
MattyB95/AST-VoxCelebSpoof-Synthetic-Voice-Detection VoxCelebSpoof

Wav2Vec2

Model Dataset
Gustking/wav2vec2-large-xlsr-deepfake-audio-classification ASVspoof2019

HuBERT

Model Dataset
abhishtagatya/hubert-base-960h-itw-deepfake In-The-Wild

WavLM

Model Dataset
DavidCombei/wavLM-base-Deepfake_V2 Mixed

Other

Model Paper Codebase
Classical Built-in KNN baseline
RawNet2 Tak et al., ICASSP 2021 rawnet2-antispoofing

Usage

Command Line Interface

usage: jabberjay [-h] [-m {AST,Classical,HuBERT,RawNet2,VIT,Wav2Vec2,WavLM}]
                 [-d {ASVspoof2019,ASVspoof5,VoxCelebSpoof}]
                 [-vis {ConstantQ,MelSpectrogram,MFCC}] [-v]
                 audio
# Quickstart — VIT with ConstantQ on VoxCelebSpoof (defaults)
jabberjay audio.wav

# Self-contained models (no dataset or visualisation required)
jabberjay audio.wav -m Wav2Vec2
jabberjay audio.wav -m HuBERT
jabberjay audio.wav -m WavLM
jabberjay audio.wav -m RawNet2

# AST with a specific dataset
jabberjay audio.wav -m AST -d ASVspoof2019

# VIT with full options
jabberjay audio.wav -m VIT -d ASVspoof5 -vis MelSpectrogram

# Verbose output
jabberjay audio.wav -v

Python API

All public names are importable from the top-level package:

from Jabberjay import Jabberjay, DetectionResult, Model, Dataset, Visualisation

Choosing a model

String names and enum values are both accepted:

jj = Jabberjay()

# Self-contained models — no extra arguments needed
result = jj.detect("audio.wav", model="Wav2Vec2")
result = jj.detect("audio.wav", model="HuBERT")
result = jj.detect("audio.wav", model="WavLM")
result = jj.detect("audio.wav", model="RawNet2")
result = jj.detect("audio.wav", model="Classical")

# AST — requires a dataset
result = jj.detect("audio.wav", model="AST", dataset="VoxCelebSpoof")

# VIT — requires a dataset and a visualisation
result = jj.detect("audio.wav", model="VIT", dataset="ASVspoof5", visualisation="MFCC")

# Enums give IDE autocomplete and catch typos at import time
result = jj.detect(
    "audio.wav",
    model=Model.VIT,
    dataset=Dataset.ASVspoof5,
    visualisation=Visualisation.MFCC,
)

DetectionResult

Every call to detect() returns a DetectionResult regardless of the model used:

Attribute Type Description
label str "Bonafide" or "Spoof"
is_bonafide bool True if the audio is classified as genuine
confidence float Confidence score for the top prediction (0.0–1.0)
model Model The model that produced this result
scores list[dict] | None Full label/score breakdown for VIT, AST, Wav2Vec2, HuBERT, and WavLM (sorted highest-first); None for Classical and RawNet2
if result.is_bonafide:
    print(f"Genuine voice detected with {result.confidence:.1%} confidence")
else:
    print(f"Synthetic voice detected with {result.confidence:.1%} confidence")

# Full per-label scores
if result.scores:
    for entry in result.scores:
        print(f"  {entry['label']}: {entry['score']:.3f}")

Pre-loading audio

Use load() when running multiple models on the same clip to avoid re-reading the file:

audio = jj.load("audio.wav")  # returns (samples, sample_rate)

results = [
    jj.detect(audio, model="Wav2Vec2"),
    jj.detect(audio, model="HuBERT"),
    jj.detect(audio, model="VIT", dataset="VoxCelebSpoof", visualisation="ConstantQ"),
]

Discovering available options

jj.list_models()         # prints and returns list[Model]
jj.list_datasets()       # prints and returns list[Dataset]
jj.list_visualisations() # prints and returns list[Visualisation]

Examples

The examples/ directory contains focused, runnable scripts:

Script What it shows
quickstart.py Minimum viable usage
choosing_a_model.py Every model family, string and enum APIs
preloading_audio.py Efficient multi-model runs with jj.load()
exploring_results.py All DetectionResult fields and score breakdown
run_all.py Exhaustive sweep across every model combination
just example                           # run quickstart
just run-example preloading_audio      # run a specific example
just run-all                           # full sweep (slow — downloads all models)

Developer Setup

Requires uv and just.

git clone https://github.com/MattyB95/Jabberjay.git
cd Jabberjay
just install   # install all dependencies including dev tools
Command Description
just test Run the test suite
just check Lint, format check, and type check
just fix Auto-fix lint issues and reformat
just detect audio.wav Run the CLI against a file
just build Build the package

See just --list for all available commands.


Contributing

Contributions are welcome — especially new models! See CONTRIBUTING.md for a full guide.

The quickest way to make an impact is to open a model request issue with a HuggingFace link and licence details.


Support

If Jabberjay saves you time, consider supporting its development:


Citation

If you use Jabberjay in your research, please cite it. GitHub's "Cite this repository" button (in the sidebar) will generate APA or BibTeX automatically from the CITATION.cff file, or you can use the entry below directly:

@software{boakes_jabberjay_2026,
  author  = {Boakes, Matthew},
  title   = {Jabberjay},
  year    = {2026},
  url     = {https://github.com/MattyB95/Jabberjay},
  version = {0.0.8.post1},
  doi     = {10.5281/zenodo.19057457},
}

Archived versions are available on Zenodo. The concept DOI (10.5281/zenodo.19057457) always resolves to the latest release.


Acknowledgement

This work was supported, in whole or in part, by the Bill & Melinda Gates Foundation [INV-001309].

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jabberjay-0.0.8.post1.tar.gz (579.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jabberjay-0.0.8.post1-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file jabberjay-0.0.8.post1.tar.gz.

File metadata

  • Download URL: jabberjay-0.0.8.post1.tar.gz
  • Upload date:
  • Size: 579.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for jabberjay-0.0.8.post1.tar.gz
Algorithm Hash digest
SHA256 82db79154133e8b8586266b27147451e73e1b27d05b75ea20ac9e53fef853793
MD5 e9aeb0ba3d1dff21e7530f7ab7f8e464
BLAKE2b-256 808904571c6896d55b1e4ae9e9eafb3add4d0c0512b5c16a1700bde00a12034d

See more details on using hashes here.

File details

Details for the file jabberjay-0.0.8.post1-py3-none-any.whl.

File metadata

  • Download URL: jabberjay-0.0.8.post1-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for jabberjay-0.0.8.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 e5c33f92630af26579b5d21c07fb81a3333ac9238e20ca629e2ebf6d7722afa0
MD5 b5ec1078ffc05b3740b0065155358d08
BLAKE2b-256 579977be2e5b551e3923f718540d807283340bc9118658dd39f814d1e2725bd1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page