Skip to main content

wakewordkit

Lightweight, developer-friendly wake word detection built on openWakeWord.

Ships with every default openWakeWord wake word and lets you plug in your own trained models through the same tiny API. Requires Python 3.12+.

Install

pip install wakewordkit          # core
pip install 'wakewordkit[mic]'   # + microphone input

Quick start

from wakewordkit import WakeWordDetector, WakeWord

detector = WakeWordDetector(WakeWord.ALEXA)

for detection in detector.listen():
    print(f"{detection.name} ({detection.score:.2f})")

listen() opens the default microphone (requires the mic extra) and yields a Detection every time a wake word is heard.

Built-in wake words

WakeWord.ALEXA
WakeWord.HEY_JARVIS
WakeWord.HEY_MYCROFT
WakeWord.HEY_MARVIN

Listen for several at once, or leave it empty to listen for all of them:

WakeWordDetector(WakeWord.HEY_JARVIS, WakeWord.HEY_MYCROFT)
WakeWordDetector()  # all built-in wake words

Custom wake words

Point CustomWakeWord at any openWakeWord-compatible .onnx model:

from wakewordkit import WakeWordDetector, WakeWord, CustomWakeWord

detector = WakeWordDetector(
    WakeWord.ALEXA,
    CustomWakeWord("hey_computer", "models/hey_computer.onnx"),
    threshold=0.6,
)

for detection in detector.listen():
    print(detection.name)  # "alexa" or "hey_computer"

Bring your own audio

Skip the built-in microphone and feed raw 16 kHz mono PCM yourself. Frames may be bytes (int16) or a NumPy array, ideally 1280 samples (80 ms) each.

detector = WakeWordDetector(WakeWord.HEY_JARVIS)

# Frame at a time
if detection := detector.process(frame):
    handle(detection)

# Or stream from any iterable of frames
for detection in detector.stream(my_audio_source):
    handle(detection)

asyncio

Every method has an async twin: alisten() for a blocking AudioInput (reads run in the default executor) and astream() for your own async frames.

detector = WakeWordDetector(WakeWord.HEY_MYCROFT)

async for detection in detector.alisten():
    await handle(detection)

No frames are read while the body of the async for runs, so handling a detection pauses detection without pausing the underlying capture — useful when the microphone is shared with a recorder.

Already have a microphone object? CallableInput adapts it without subclassing:

from wakewordkit import CallableInput

source = CallableInput(my_mic.read, 1280)  # calls my_mic.read(1280)

async for detection in detector.alisten(source):
    await handle(detection)

CallableInput never closes the underlying source unless you pass close=my_mic.close, so sharing a stream is safe.

Bring your own audio source

Microphone is only one implementation of the AudioInput interface. Subclass it to plug in any source — a socket, a file, another capture library — and pass it to listen():

from wakewordkit import AudioInput, WakeWordDetector, WakeWord


class FileInput(AudioInput):
    def __init__(self, path):
        self._reader = open_pcm(path)

    def read(self):
        frame = self._reader.read(1280)
        if not frame:
            raise StopIteration
        return frame


detector = WakeWordDetector(WakeWord.HEY_MYCROFT)
for detection in detector.listen(FileInput("recording.pcm")):
    handle(detection)

Override __enter__ / __exit__ for setup and teardown; read() is the only required method.

API

Object Purpose
WakeWord Enum of built-in wake words.
CustomWakeWord(name, model) Wraps a custom .onnx model under a chosen name.
WakeWordDetector(*wake_words, threshold=0.5, vad_threshold=0.0, cooldown=1.5) The detector.
WakeWordDetector.listen(source=None) Iterate detections from an AudioInput (defaults to Microphone).
WakeWordDetector.stream(source) Iterate detections from your own frames.
WakeWordDetector.alisten(source=None) listen() for asyncio; reads in the default executor.
WakeWordDetector.astream(source) stream() for asyncio; takes an async iterable of frames.
WakeWordDetector.process(frame) Score a single frame, returns Detection or None.
WakeWordDetector.reset() Clear detection state.
Detection(name, score) A single detection result.
AudioInput Abstract audio source; implement read().
CallableInput(read, frame_size=None, *, close=None) Wrap an existing read function as an AudioInput.
Microphone(*, samplerate=16000, frame_size=1280, device=None) Context-managed 16 kHz mic (AudioInput).

vad_threshold (0 disables) turns on openWakeWord's Silero voice-activity filter to suppress non-speech false triggers. cooldown is the minimum number of seconds between two detections, so a single utterance triggers only once.

Development

uv sync --dev
uv run pytest

See CONTRIBUTING.md for the full workflow.

License

MIT — see LICENSE.

Download files

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

Source Distribution

wakewordkit-0.2.0.tar.gz (47.9 kB view details)

Uploaded Source

Built Distribution

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

wakewordkit-0.2.0-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file wakewordkit-0.2.0.tar.gz.

File metadata

  • Download URL: wakewordkit-0.2.0.tar.gz
  • Upload date:
  • Size: 47.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for wakewordkit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2848c0c00d5d1c7dc97c3c0055876c265655d363125eed15c340c81e30073edf
MD5 3461dee3fb6cb2a8a7aa244eb5659268
BLAKE2b-256 c2e9ed559f922857de104b1bcffe5eacadded0ce97abd2b7b5535385bf6eafbe

See more details on using hashes here.

File details

Details for the file wakewordkit-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for wakewordkit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 07ea85f6840a6056b0646e0e7e2bf233a35d8fd02af8595dc380c7d2f63d6c42
MD5 06c8bdc994b5f49a54058a8355e5c479
BLAKE2b-256 a794223fb05460ea8a43325b297b2a96a72c181a11ea4e1674d72cf7fb97cc7e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.0

2 files

This release

0.2.0 This release

2 files

0.1.0

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