Quick start: Python
pip install alkoveThe 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.
The models
Section titled “The models”import alkove
models = alkove.Models.load(["focus", "cue"]) # from Hugging Face at this version's revision, then the cachemodels = alkove.Models.load(["focus", "cue"], dir="models") # a folder of .alk files, nothing on the networkEach 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.
A stream
Section titled “A stream”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.
A file
Section titled “A file”r = alkove.process(models, pcm, rate=44100, focus=True, cue=True)r.audio # as long as the input, at 16 kHzr.speech # [Speech(start, end)]A wake word
Section titled “A wake word”models = alkove.Models.load(["spot", "lex"])word = alkove.Lex(models).compile("Camille", "fr") # or alkove.compile("/kamij/") without Lexstore(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.
A voice
Section titled “A voice”models = alkove.Models.load(["timbre", "focus", "cue"])timbre = alkove.Timbre(models)me = timbre.embed(pcm) # 1.5 s of voice or moresame, score = alkove.Timbre.verify(me, timbre.embed(other))p = alkove.Processor(models, focus=True, voiceprint=me) # Focus keeps that voice, not just the closest onealkove.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.
Errors
Section titled “Errors”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.