Skip to main content

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.

  • Ten model families — ViT, AST, Spectra0, SpectraAASIST, SpectraAASIST3, 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.11. 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

Spectra Family (lab260)

Model Architecture
lab260/spectra_0 Wav2Vec2-XLS-R-300M + ECAPA-TDNN
lab260/Spectra-AASIST Wav2Vec2-XLS-R-300M + AASIST
lab260/Spectra-AASIST3 Wav2Vec2-XLS-R-300M + KAN-AASIST

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,Spectra0,SpectraAASIST,SpectraAASIST3,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 Spectra0
jabberjay audio.wav -m SpectraAASIST
jabberjay audio.wav -m SpectraAASIST3
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="Spectra0")
result = jj.detect("audio.wav", model="SpectraAASIST")
result = jj.detect("audio.wav", model="SpectraAASIST3")
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, Spectra0, SpectraAASIST, SpectraAASIST3, 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. Each model is also cached in memory after its first detect() call, so calling it again later in the process reuses the already-loaded weights instead of reloading them:

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()         # returns list[Model]
jj.list_datasets()       # returns list[Dataset]
jj.list_visualisations() # 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.15},
  doi     = {10.5281/zenodo.19056977},
}

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


Acknowledgement

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

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.15.tar.gz (570.3 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.15-py3-none-any.whl (40.2 kB view details)

Uploaded Python 3

File details

Details for the file jabberjay-0.0.15.tar.gz.

File metadata

  • Download URL: jabberjay-0.0.15.tar.gz
  • Upload date:
  • Size: 570.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","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.15.tar.gz
Algorithm Hash digest
SHA256 0b72a4de5124cca4b0510e80355578e21d998cb603a506510b0cdef213f4c965
MD5 a8985994d0b5eec699ca6586dad5fe0f
BLAKE2b-256 fe316e4db50660a1983371ddea711de97a8c1b7bb320ee52770e418881f48abd

See more details on using hashes here.

File details

Details for the file jabberjay-0.0.15-py3-none-any.whl.

File metadata

  • Download URL: jabberjay-0.0.15-py3-none-any.whl
  • Upload date:
  • Size: 40.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","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.15-py3-none-any.whl
Algorithm Hash digest
SHA256 921665c1f65577c236534334eb57b33e2776154ef1b468b67a3f10dd0e34c482
MD5 12b34b42048cdefe86254523bdb7357b
BLAKE2b-256 8b4dbf20fab81336a425c9369411ec0fdccaecd1a997580af3eda6a8f7c3e75a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.0.15 This release

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8.post2

2 files

0.0.8.post1

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page