Skip to content

Quick start: Python

Terminal window
pip install alkove

The alkove Python package runs the core the web library runs in WebAssembly, natively on the CPU: for the same 16 kHz audio, the output is the same to the bit. Wheels for Linux (x86-64, aarch64), macOS and Windows, Python 3.9 and later; numpy is the only dependency. On LiveKit or Pipecat, use the plugins: LiveKit Agents, Pipecat.

import alkove
models = alkove.Models.load(["focus", "cue"]) # from Hugging Face at this version's revision, then the cache
models = alkove.Models.load(["focus", "cue"], dir="models") # a folder of .alk files, nothing on the network

Each file is checked against the sha256 this version pins: a file that does not match raises AlkoveError with the code models.hash. alkove.fetch() downloads them ahead of time, alkove.cache_dir() says where they go. Load them once: a Models is shared by every stream, in any thread.

p = alkove.Processor(models, focus=True, cue=True, rate=48000)
for frame in frames: # float32 or int16 numpy arrays, any length
part = p.push(frame)
send(part.audio) # 16 kHz, the user's voice only
for s in part.speech: # Speech(start, end), in seconds from the start of the stream
...
last = p.end()

The output comes back aligned with the input: the first part.audio is shorter by the chain’s delay (16 ms), and end() gives it back. The options are those of Alkove.process: focus, voiceprint, strength, cue, speech, normalize, trace, rate, words and context.

push releases the GIL: streams in several threads run on several cores. alkove.Live(models, rate) gives the chain frame by frame at the stream’s own rate, as a real-time input runs it, for a pipeline that wants its audio back at the rate it came in.

r = alkove.process(models, pcm, rate=44100, focus=True, cue=True)
r.audio # as long as the input, at 16 kHz
r.speech # [Speech(start, end)]
models = alkove.Models.load(["spot", "lex"])
word = alkove.Lex(models).compile("Camille", "fr") # or alkove.compile("/kamij/") without Lex
store(word.to_json())
listener = alkove.Listener(models, [word]) # after a pause by default; context="anywhere" or "both"
for frame in mic: # 16 kHz
for heard in listener.push(frame): # one every 30 ms
for wake in heard.wakes: # word, score, threshold, context, start, end
...

alkove.Enroller(models, word) sets a word’s thresholds on the user’s own voice from three takes. A word is bound to this version’s Spot: alkove.Word.from_json gives None for a word made by another one.

models = alkove.Models.load(["timbre", "focus", "cue"])
timbre = alkove.Timbre(models)
me = timbre.embed(pcm) # 1.5 s of voice or more
same, score = alkove.Timbre.verify(me, timbre.embed(other))
p = alkove.Processor(models, focus=True, voiceprint=me) # Focus keeps that voice, not just the closest one

alkove.VoiceprintLearner(models).offer(pcm) learns a print from the user’s speech, window by window, as the web inputs do. A print is biometric data: read Voiceprints and Privacy before you store one.

A file that cannot be fetched or does not match its sha256 raises alkove.AlkoveError, with the codes of the web library. A rate outside 1 to 768 kHz raises ValueError. Every class and function: the Python reference.