use rustpotter::{
DetectedWakeword, SampleFormat as RustpotterSampleFormat, WakewordDetector,
WakewordDetectorBuilder,
};
use wasm_bindgen::prelude::*;
mod utils;
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
pub struct RustpotterJS {
detector: WakewordDetector,
}
#[wasm_bindgen]
#[allow(non_snake_case)]
impl RustpotterJS {
pub fn addWakewordModelBytes(&mut self, data: Vec<u8>) {
self.detector
.add_wakeword_from_model_bytes(data, true)
.unwrap();
}
pub fn processInt32(&mut self, buffer: &[i32]) -> Option<RustpotterDetection> {
transform_detection(self.detector.process_i32(buffer))
}
pub fn processInt16(&mut self, buffer: &[i16]) -> Option<RustpotterDetection> {
transform_detection(self.detector.process_i16(buffer))
}
pub fn processInt8(&mut self, buffer: &[i8]) -> Option<RustpotterDetection> {
transform_detection(self.detector.process_i8(buffer))
}
pub fn processFloat32(&mut self, buffer: &[f32]) -> Option<RustpotterDetection> {
transform_detection(self.detector.process_f32(buffer))
}
pub fn getFrameSize(&self) -> usize {
self.detector.get_samples_per_frame()
}
}
fn transform_detection(detection_option: Option<DetectedWakeword>) -> Option<RustpotterDetection> {
if detection_option.is_some() {
let result = detection_option.unwrap();
Some(RustpotterDetection{
name: result.wakeword.clone(),
score: result.score,
})
} else {
None
}
}
#[wasm_bindgen]
pub struct RustpotterDetection {
name: String,
score: f32,
}
#[wasm_bindgen]
#[allow(non_snake_case)]
impl RustpotterDetection {
pub fn getName(&self) -> String {
self.name.clone()
}
pub fn getScore(&self) -> f32 {
self.score
}
}
#[wasm_bindgen]
pub struct RustpotterJSBuilder {
builder: WakewordDetectorBuilder,
}
#[wasm_bindgen]
#[allow(non_snake_case)]
impl RustpotterJSBuilder {
pub fn new() -> Self {
utils::set_panic_hook();
Self {
builder: WakewordDetectorBuilder::new(),
}
}
pub fn setThreshold(&mut self, value: f32) {
self.builder.set_threshold(value);
}
pub fn setAveragedThreshold(&mut self, value: f32) {
self.builder.set_averaged_threshold(value);
}
pub fn setBitsPerSample(&mut self, value: u16) {
self.builder.set_bits_per_sample(value);
}
pub fn setSampleRate(&mut self, value: usize) {
self.builder.set_sample_rate(value);
}
pub fn setSampleFormat(&mut self, value: SampleFormat) {
self.builder.set_sample_format(transform_format(value));
}
pub fn setChannels(&mut self, value: u16) {
self.builder.set_channels(value);
}
pub fn setComparatorBandSize(&mut self, value: usize) {
self.builder.set_comparator_band_size(value);
}
pub fn setComparatorRef(&mut self, value: f32) {
self.builder.set_comparator_ref(value);
}
pub fn setEagerMode(&mut self, value: bool) {
self.builder.set_eager_mode(value);
}
pub fn setSingleThread(&mut self, value: bool) {
self.builder.set_single_thread(value);
}
pub fn build(&self) -> RustpotterJS {
RustpotterJS {
detector: self.builder.build(),
}
}
}
#[wasm_bindgen]
#[allow(non_camel_case_types)]
pub enum SampleFormat {
int,
float,
}
fn transform_format(format: SampleFormat) -> RustpotterSampleFormat {
match format {
SampleFormat::int => RustpotterSampleFormat::Int,
SampleFormat::float => RustpotterSampleFormat::Float,
}
}