diff --git a/index.html b/index.html index 6e53357..116a633 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + Tauri + Svelte + TS diff --git a/package.json b/package.json index 630c460..f993033 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jarvis-app", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "routify -c dev:vite", diff --git a/public/media/app-icon.png b/public/media/app-icon.png new file mode 100644 index 0000000..a55b393 Binary files /dev/null and b/public/media/app-icon.png differ diff --git a/public/media/app-logo.png b/public/media/app-logo.png index f98152d..2ca037b 100644 Binary files a/public/media/app-logo.png and b/public/media/app-logo.png differ diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore index 2de70eb..fca3f36 100644 --- a/src-tauri/.gitignore +++ b/src-tauri/.gitignore @@ -1,4 +1,5 @@ # Generated by Cargo # will have compiled files and executables /target/ -app.db \ No newline at end of file +app.db +log.txt \ No newline at end of file diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 55986bc..25a3cf1 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -312,6 +312,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clang-sys" version = "1.6.1" @@ -1145,6 +1172,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1332,16 +1365,20 @@ version = "0.0.1" dependencies = [ "hound", "lazy_static", + "log", + "once_cell", "peak_alloc", "pickledb", "pv_porcupine", "pv_recorder", "rand 0.8.5", "rodio", + "rustpotter", "seqdiff", "serde", "serde_json", "serde_yaml", + "simple-logging", "systemstat", "tauri", "tauri-build", @@ -1721,6 +1758,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2129,6 +2175,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "primal-check" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df7f93fd637f083201473dab4fee2db4c429d32e55e3299980ab3957ab916a0" +dependencies = [ + "num-integer", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2303,6 +2358,21 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "realfft" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6b8e8f0c6d2234aa58048d7290c60bf92cd36fd2888cd8331c66ad4f2e1d2" +dependencies = [ + "rustfft", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2401,6 +2471,18 @@ dependencies = [ "symphonia", ] +[[package]] +name = "rubato" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd70209c27d5b08f5528bdc779ea3ffb418954e28987f9f9775c6eac41003f9c" +dependencies = [ + "num-complex", + "num-integer", + "num-traits", + "realfft", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2416,6 +2498,21 @@ dependencies = [ "semver", ] +[[package]] +name = "rustfft" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d4f6cbdb180c9f4b2a26bbf01c4e647f1e1dea22fe8eb9db54198b32f9434" +dependencies = [ + "num-complex", + "num-integer", + "num-traits", + "primal-check", + "strength_reduce", + "transpose", + "version_check", +] + [[package]] name = "rustix" version = "0.37.13" @@ -2430,6 +2527,19 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustpotter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a88d0514dd5dcc988c78f61be4f60fdb37d4872e23c7d8d6d2d3ea23655f97" +dependencies = [ + "ciborium", + "hound", + "rubato", + "rustfft", + "serde", +] + [[package]] name = "rustversion" version = "1.0.12" @@ -2654,6 +2764,17 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +[[package]] +name = "simple-logging" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00d48e85675326bb182a2286ea7c1a0b264333ae10f27a937a72be08628b542" +dependencies = [ + "lazy_static", + "log", + "thread-id", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -2718,6 +2839,12 @@ dependencies = [ "loom", ] +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + [[package]] name = "string_cache" version = "0.8.7" @@ -3147,6 +3274,17 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall 0.1.57", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.7" @@ -3317,6 +3455,16 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "transpose" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6522d49d03727ffb138ae4cbc1283d3774f0d10aa7f9bf52e6784c45daf9b23" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "treediff" version = "3.0.2" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c92de71..3bf2065 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -27,11 +27,15 @@ systemstat = "0.2.3" hound = "3.5.0" pv_recorder = "1.1.1" pv_porcupine = "2.2.0" -rodio = "0.17.1" serde_yaml = "0.9.21" seqdiff = "0.3.0" vosk = "0.2.0" rand = "0.8.5" +rodio = "0.17.1" +rustpotter = "2.0.0" +simple-logging = "2.0.2" +log = "0.4.17" +once_cell = "1.17.1" [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 0457690..3623023 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,8 +1,6 @@ fn main() { // link to Vosk lib - println!("cargo:rustc-link-search=vosk/"); - - // println!("cargo:rustc-link-lib=dylib=D:/Rust/vosk/libvosk.dll"); + println!("cargo:rustc-link-lib=libvosk.dll"); // Tauri build tauri_build::build() diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png index 6be5e50..e1454fc 100644 Binary files a/src-tauri/icons/128x128.png and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png index e81bece..68626e0 100644 Binary files a/src-tauri/icons/128x128@2x.png and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png index a437dd5..cf48517 100644 Binary files a/src-tauri/icons/32x32.png and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png index 0ca4f27..1b8d3ce 100644 Binary files a/src-tauri/icons/Square107x107Logo.png and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png index b81f820..4bce679 100644 Binary files a/src-tauri/icons/Square142x142Logo.png and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png index 624c7bf..7da8d34 100644 Binary files a/src-tauri/icons/Square150x150Logo.png and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png index c021d2b..21d6359 100644 Binary files a/src-tauri/icons/Square284x284Logo.png and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png index 6219700..11d6bce 100644 Binary files a/src-tauri/icons/Square30x30Logo.png and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png index f9bc048..af30f2a 100644 Binary files a/src-tauri/icons/Square310x310Logo.png and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png index d5fbfb2..ac8e01e 100644 Binary files a/src-tauri/icons/Square44x44Logo.png and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png index 63440d7..cde0658 100644 Binary files a/src-tauri/icons/Square71x71Logo.png and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png index f3f705a..cb241b8 100644 Binary files a/src-tauri/icons/Square89x89Logo.png and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png index 4556388..e3fa9eb 100644 Binary files a/src-tauri/icons/StoreLogo.png and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 12a5bce..49e4def 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index b3636e4..180e0d4 100644 Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png index e1cd261..79bc4e4 100644 Binary files a/src-tauri/icons/icon.png and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/libpv_recorder.dll b/src-tauri/libpv_recorder.dll deleted file mode 100644 index c3f4dbc..0000000 Binary files a/src-tauri/libpv_recorder.dll and /dev/null differ diff --git a/src-tauri/vosk/libvosk.lib b/src-tauri/libvosk.lib similarity index 100% rename from src-tauri/vosk/libvosk.lib rename to src-tauri/libvosk.lib diff --git a/src-tauri/picovoice/keywords/alexa_windows.ppn b/src-tauri/picovoice/keywords/alexa_windows.ppn deleted file mode 100644 index 5e58ac9..0000000 Binary files a/src-tauri/picovoice/keywords/alexa_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/americano_windows.ppn b/src-tauri/picovoice/keywords/americano_windows.ppn deleted file mode 100644 index 160e7b2..0000000 Binary files a/src-tauri/picovoice/keywords/americano_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/blueberry_windows.ppn b/src-tauri/picovoice/keywords/blueberry_windows.ppn deleted file mode 100644 index 4ff1c32..0000000 Binary files a/src-tauri/picovoice/keywords/blueberry_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/bumblebee_windows.ppn b/src-tauri/picovoice/keywords/bumblebee_windows.ppn deleted file mode 100644 index e25665f..0000000 Binary files a/src-tauri/picovoice/keywords/bumblebee_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/computer_windows.ppn b/src-tauri/picovoice/keywords/computer_windows.ppn deleted file mode 100644 index 24bc79e..0000000 Binary files a/src-tauri/picovoice/keywords/computer_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/grapefruit_windows.ppn b/src-tauri/picovoice/keywords/grapefruit_windows.ppn deleted file mode 100644 index 3c11353..0000000 Binary files a/src-tauri/picovoice/keywords/grapefruit_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/grasshopper_windows.ppn b/src-tauri/picovoice/keywords/grasshopper_windows.ppn deleted file mode 100644 index 21720c1..0000000 Binary files a/src-tauri/picovoice/keywords/grasshopper_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/hey barista_windows.ppn b/src-tauri/picovoice/keywords/hey barista_windows.ppn deleted file mode 100644 index fc548d1..0000000 Binary files a/src-tauri/picovoice/keywords/hey barista_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/hey google_windows.ppn b/src-tauri/picovoice/keywords/hey google_windows.ppn deleted file mode 100644 index 73868a7..0000000 Binary files a/src-tauri/picovoice/keywords/hey google_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/hey siri_windows.ppn b/src-tauri/picovoice/keywords/hey siri_windows.ppn deleted file mode 100644 index 73c660f..0000000 Binary files a/src-tauri/picovoice/keywords/hey siri_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/ok google_windows.ppn b/src-tauri/picovoice/keywords/ok google_windows.ppn deleted file mode 100644 index 01d225f..0000000 Binary files a/src-tauri/picovoice/keywords/ok google_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/pico clock_windows.ppn b/src-tauri/picovoice/keywords/pico clock_windows.ppn deleted file mode 100644 index bd36be5..0000000 Binary files a/src-tauri/picovoice/keywords/pico clock_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/picovoice_windows.ppn b/src-tauri/picovoice/keywords/picovoice_windows.ppn deleted file mode 100644 index 8ce42f3..0000000 Binary files a/src-tauri/picovoice/keywords/picovoice_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/porcupine_windows.ppn b/src-tauri/picovoice/keywords/porcupine_windows.ppn deleted file mode 100644 index ab1bce5..0000000 Binary files a/src-tauri/picovoice/keywords/porcupine_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/keywords/terminator_windows.ppn b/src-tauri/picovoice/keywords/terminator_windows.ppn deleted file mode 100644 index 598f00c..0000000 Binary files a/src-tauri/picovoice/keywords/terminator_windows.ppn and /dev/null differ diff --git a/src-tauri/picovoice/lib/android/arm64-v8a/libpv_porcupine.so b/src-tauri/picovoice/lib/android/arm64-v8a/libpv_porcupine.so deleted file mode 100644 index 05eeaf4..0000000 Binary files a/src-tauri/picovoice/lib/android/arm64-v8a/libpv_porcupine.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/android/armeabi-v7a/libpv_porcupine.so b/src-tauri/picovoice/lib/android/armeabi-v7a/libpv_porcupine.so deleted file mode 100644 index a680d96..0000000 Binary files a/src-tauri/picovoice/lib/android/armeabi-v7a/libpv_porcupine.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/android/x86/libpv_porcupine.so b/src-tauri/picovoice/lib/android/x86/libpv_porcupine.so deleted file mode 100644 index a6f97b7..0000000 Binary files a/src-tauri/picovoice/lib/android/x86/libpv_porcupine.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/android/x86_64/libpv_porcupine.so b/src-tauri/picovoice/lib/android/x86_64/libpv_porcupine.so deleted file mode 100644 index 46bf24c..0000000 Binary files a/src-tauri/picovoice/lib/android/x86_64/libpv_porcupine.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/linux/x86_64/libpv_porcupine.so b/src-tauri/picovoice/lib/linux/x86_64/libpv_porcupine.so deleted file mode 100644 index e4243be..0000000 Binary files a/src-tauri/picovoice/lib/linux/x86_64/libpv_porcupine.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/linux/x86_64/libpv_recorder.so b/src-tauri/picovoice/lib/linux/x86_64/libpv_recorder.so deleted file mode 100644 index 65a39ec..0000000 Binary files a/src-tauri/picovoice/lib/linux/x86_64/libpv_recorder.so and /dev/null differ diff --git a/src-tauri/picovoice/lib/mac/arm64/libpv_porcupine.dylib b/src-tauri/picovoice/lib/mac/arm64/libpv_porcupine.dylib deleted file mode 100644 index f196f48..0000000 Binary files a/src-tauri/picovoice/lib/mac/arm64/libpv_porcupine.dylib and /dev/null differ diff --git a/src-tauri/picovoice/lib/mac/arm64/libpv_recorder.dylib b/src-tauri/picovoice/lib/mac/arm64/libpv_recorder.dylib deleted file mode 100644 index 82b1d4a..0000000 Binary files a/src-tauri/picovoice/lib/mac/arm64/libpv_recorder.dylib and /dev/null differ diff --git a/src-tauri/picovoice/lib/mac/x86_64/libpv_porcupine.dylib b/src-tauri/picovoice/lib/mac/x86_64/libpv_porcupine.dylib deleted file mode 100644 index 8a1ade7..0000000 Binary files a/src-tauri/picovoice/lib/mac/x86_64/libpv_porcupine.dylib and /dev/null differ diff --git a/src-tauri/picovoice/lib/mac/x86_64/libpv_recorder.dylib b/src-tauri/picovoice/lib/mac/x86_64/libpv_recorder.dylib deleted file mode 100644 index 0f798bf..0000000 Binary files a/src-tauri/picovoice/lib/mac/x86_64/libpv_recorder.dylib and /dev/null differ diff --git a/src-tauri/src/assistant_commands.rs b/src-tauri/src/assistant_commands.rs index d0c0719..0a44135 100644 --- a/src-tauri/src/assistant_commands.rs +++ b/src-tauri/src/assistant_commands.rs @@ -8,7 +8,7 @@ use core::time::Duration; use std::path::PathBuf; use std::process::Child; use std::process::Command; -use tauri::Manager; +// use tauri::Manager; mod structs; pub use structs::*; diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 0bb70b2..3ecb824 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -1,5 +1,4 @@ -use const_concat::const_concat; -use std::env::current_dir; +// use const_concat::const_concat; // pub const IS_DEV: bool = cfg!(debug_assertions);// cfg!(debug_assertions); // pub const PUBLIC_PATH: &str = if IS_DEV { @@ -8,14 +7,17 @@ use std::env::current_dir; // "./public" // }; -pub const COMMANDS_PATH: &str = "commands/"; -pub const KEYWORDS_PATH: &str = "picovoice/keywords/"; +pub const WAKE_WORD_ENGINES: [&str; 2] = ["rustpotter", "picovoice"]; pub const DB_FILE_NAME: &str = "app.db"; +pub const LOG_FILE_NAME: &str = "log.txt"; pub const APP_VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION"); pub const AUTHOR_NAME: Option<&str> = option_env!("CARGO_PKG_AUTHORS"); pub const REPOSITORY_LINK: Option<&str> = option_env!("CARGO_PKG_REPOSITORY"); +pub const COMMANDS_PATH: &str = "commands/"; +pub const KEYWORDS_PATH: &str = "picovoice/keywords/"; + // pub const VOSK_MODEL_PATH: &str = const_concat!(PUBLIC_PATH, "/vosk/model_small"); pub const VOSK_MODEL_PATH: &str = "vosk/model_small"; diff --git a/src-tauri/src/events.rs b/src-tauri/src/events.rs index a6ba3d4..bd07d8c 100644 --- a/src-tauri/src/events.rs +++ b/src-tauri/src/events.rs @@ -6,6 +6,7 @@ pub struct Payload { pub data: String, } +#[allow(dead_code)] pub enum EventTypes { AudioPlay, AssistantWaiting, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index bdc52cb..4f66a52 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,6 +4,8 @@ #[macro_use] extern crate lazy_static; // better switch to once_cell ? use pickledb::{PickleDb, PickleDbDumpPolicy, SerializationMethod}; +use log::{info}; +use log::LevelFilter; use std::sync::Mutex; // expose the config @@ -23,6 +25,9 @@ mod vosk; // include events mod events; +// include recorder +mod recorder; + // app dir lazy_static! { static ref APP_CONFIG_DIR: Mutex = Mutex::new(String::new()); @@ -37,7 +42,7 @@ lazy_static! { SerializationMethod::Json ) .unwrap_or_else(|_x: _| { - println!("Creating new db file at {} ...", format!("{}/{}", APP_CONFIG_DIR.lock().unwrap(), DB_FILE_NAME)); + info!("Creating new db file at {} ...", format!("{}/{}", APP_CONFIG_DIR.lock().unwrap(), DB_FILE_NAME)); PickleDb::new( format!("{}/{}", APP_CONFIG_DIR.lock().unwrap(), DB_FILE_NAME), PickleDbDumpPolicy::AutoDump, @@ -53,8 +58,13 @@ lazy_static! { } fn main() { + // log to file + simple_logging::log_to_file(config::LOG_FILE_NAME, LevelFilter::max()).expect("Failed to start logger ... is directory writable?"); + + // init vosk vosk::init_vosk(); + // run the app tauri::Builder::default() .setup(|app| { std::fs::create_dir_all(app.path_resolver().app_config_dir().unwrap())?; diff --git a/src-tauri/src/recorder.rs b/src-tauri/src/recorder.rs new file mode 100644 index 0000000..f8fad40 --- /dev/null +++ b/src-tauri/src/recorder.rs @@ -0,0 +1,63 @@ +use once_cell::sync::OnceCell; +use std::sync::atomic::{AtomicU32, AtomicBool, Ordering}; +use pv_recorder::{Recorder, RecorderBuilder}; +use log::{info}; + +use crate::DB; + +pub static FRAME_LENGTH: AtomicU32 = AtomicU32::new(0); +static RECORDER: OnceCell = OnceCell::new(); +pub static IS_RECORDING: AtomicBool = AtomicBool::new(false); + +fn init_microphone() { + if RECORDER.get().is_none() { + RECORDER.get_or_init(|| RecorderBuilder::new() + .device_index(get_selected_microphone_index()) + .frame_length(FRAME_LENGTH.load(Ordering::SeqCst) as i32) + .init() + .expect("Failed to initialize pvrecorder")); + + info!("Microphone recorder initialized!") + } +} + +pub fn read_microphone(frame_buffer: &mut [i16]) { + // ensure microphone is initialized + init_microphone(); + + // read to frame buffer + RECORDER.get().unwrap().read(frame_buffer).expect("Failed to read audio frame"); +} + +pub fn start_recording() { + // ensure microphone is initialized + init_microphone(); + + RECORDER.get().unwrap().start().expect("Failed to start audio recording!"); + IS_RECORDING.store(true, Ordering::SeqCst); + info!("START recording from microphone ..."); +} + +pub fn stop_recording() { + // ensure microphone is initialized + init_microphone(); + + RECORDER.get().unwrap().start().expect("Failed to start audio recording!"); + IS_RECORDING.store(false, Ordering::SeqCst); + info!("STOP recording from microphone ..."); +} + +pub fn get_selected_microphone_index() -> i32 { + let selected_microphone: i32; + + // Retrieve microphone index + if let Some(smic) = DB.lock().unwrap().get::("selected_microphone") { + selected_microphone = smic.parse().unwrap_or(-1); + } else { + selected_microphone = -1; + } + + // return microphone index + info!("Selected microphone index = {selected_microphone}"); + selected_microphone +} \ No newline at end of file diff --git a/src-tauri/src/tauri_commands/listener.rs b/src-tauri/src/tauri_commands/listener.rs index 0c021c9..cdd5f9e 100644 --- a/src-tauri/src/tauri_commands/listener.rs +++ b/src-tauri/src/tauri_commands/listener.rs @@ -1,9 +1,9 @@ -use porcupine::{BuiltinKeywords, Porcupine, PorcupineBuilder}; -use pv_recorder::RecorderBuilder; +use porcupine::{Porcupine, PorcupineBuilder}; use std::sync::atomic::{AtomicBool, Ordering}; use std::path::Path; +use log::{info, warn, error}; -use crate::events::Payload; +// use crate::events::Payload; use tauri::Manager; use rand::seq::SliceRandom; @@ -14,6 +14,7 @@ use crate::events; use crate::config; use crate::vosk; +use crate::recorder; use crate::COMMANDS; use crate::DB; @@ -46,154 +47,173 @@ pub fn start_listening(app_handle: tauri::AppHandle) -> Result { return Err("Already listening.".into()); } - // vars - let porcupine: Porcupine; - let mut picovoice_api_key: String = String::from(""); - let selected_microphone: i32; + // Retrieve selected wake-word engine from DB + let selected_wake_word_engine; + if let Some(wwengine) = DB.lock().unwrap().get::("selected_wake_word_engine") { + // from db + selected_wake_word_engine = wwengine; + } else { + // default + selected_wake_word_engine = config::WAKE_WORD_ENGINES.first().expect("No wake-word engines found ...").to_string(); // set default wake_word engine + } - let mut start = SystemTime::now(); + // call selected wake-word engine listener command + match selected_wake_word_engine.as_str() { + "rustpotter" => { + info!("Starting rustpotter wake-word engine ..."); + return picovoice_listen(&app_handle, |_app| { + // Greet user + events::play("run", &app_handle); + }, |app, kidx| keyword_callback(app, kidx)); + }, + "picovoice" => { + info!("Starting picovoice wake-word engine ..."); + return picovoice_listen(&app_handle, |_app| { + // Greet user + events::play("run", &app_handle); + }, |app, kidx| keyword_callback(app, kidx)); + }, + _ => Err("No wake-word engine selected ...".into()) + } +} + +pub fn keyword_callback(app_handle: &tauri::AppHandle, _keyword_index: i32) { + // vars + let mut start: SystemTime = SystemTime::now(); + let mut frame_buffer = vec![0; recorder::FRAME_LENGTH.load(Ordering::SeqCst) as usize]; + + // play greet phrase + events::play( + config::ASSISTANT_GREET_PHRASES + .choose(&mut rand::thread_rng()) + .unwrap(), + &app_handle, + ); + + // emit assistant greet event + app_handle + .emit_all(events::EventTypes::AssistantGreet.get(), ()) + .unwrap(); + + // the loop + while !STOP_LISTENING.load(Ordering::SeqCst) { + recorder::read_microphone(&mut frame_buffer); + + // vosk part (partials included) + if let Some(mut test) = vosk::recognize(&frame_buffer) { + if !test.is_empty() { + println!("Recognized: {}", test); + + // some filtration + test = test.to_lowercase(); + for tbr in config::ASSISTANT_PHRASES_TBR { + test = test.replace(tbr, ""); + } + + // infer command + if let Some((cmd_path, cmd_config)) = + assistant_commands::fetch_command(&test, &COMMANDS) + { + println!("Recognized (filtered): {}", test); + println!("Command found: {:?}", cmd_path); + println!("Executing ..."); + + let cmd_result = assistant_commands::execute_command( + &cmd_path, + &cmd_config, + &app_handle, + ); + + match cmd_result { + Ok(_) => { + println!("Command executed successfully!"); + start = SystemTime::now(); // listen for more commands + continue; + } + Err(error_message) => { + println!("Error executing command: {}", error_message); + } + } + + app_handle + .emit_all(events::EventTypes::AssistantWaiting.get(), ()) + .unwrap(); + break; // return to picovoice after command execution (no matter successfull or not) + } + } + } + + match start.elapsed() { + Ok(elapsed) if elapsed > config::CMS_WAIT_DELAY => { + // return to picovoice after N seconds + app_handle + .emit_all(events::EventTypes::AssistantWaiting.get(), ()) + .unwrap(); + break; + } + _ => (), + } + } +} + +pub fn picovoice_listen<'s, S, K>(app_handle: &tauri::AppHandle, start_callback: S, mut keyword_callback: K) -> Result + where S: Fn(&tauri::AppHandle), + K: FnMut(&tauri::AppHandle, i32) { + + // VARS + let porcupine: Porcupine; + let picovoice_api_key: String; // Retrieve API key from DB if let Some(pkey) = DB.lock().unwrap().get::("api_key__picovoice") { - if !pkey.is_empty() { - picovoice_api_key = pkey; - } - } - - if picovoice_api_key.is_empty() { + picovoice_api_key = pkey; + } else { + warn!("Picovoice API key is not set!"); return Err("Picovoice API key is not set!".into()); } // Create instance of Porcupine with the given API key match PorcupineBuilder::new_with_keyword_paths(picovoice_api_key, &[Path::new(config::KEYWORDS_PATH).join("jarvis_windows.ppn")]) - .sensitivities(&[1.0f32]) // max sensitivity possible - .init() { - Ok(pinstance) => { - // porcupine successfully initialized with the valid API key - println!("Porcupine successfully initialized with the valid API key ..."); - porcupine = pinstance; - } - Err(e) => { - println!("Porcupine error: either API key is not valid or there is no internet connection"); - println!("Error details: {}", e); - return Err( - "Porcupine error: either API key is not valid or there is no internet connection" - .into(), - ); - } + .sensitivities(&[1.0f32]) // max sensitivity possible + .init() { + Ok(pinstance) => { + // porcupine successfully initialized with the valid API key + info!("Porcupine successfully initialized with the valid API key ..."); + porcupine = pinstance; + } + Err(e) => { + error!("Porcupine error: either API key is not valid or there is no internet connection"); + error!("Error details: {}", e); + return Err( + "Porcupine error: either API key is not valid or there is no internet connection" + .into(), + ); + } } - // Retrieve microphone index - if let Some(smic) = DB.lock().unwrap().get::("selected_microphone") { - selected_microphone = smic.parse().unwrap_or(-1); - } else { - selected_microphone = -1; // use default, if not selected - } - - // Create recorder instance - let recorder = RecorderBuilder::new() - .device_index(selected_microphone) - .frame_length(porcupine.frame_length() as i32) - .init() - .expect("Failed to initialize pvrecorder"); - // Start recording - println!("Listening (microphone idx = {selected_microphone}) ..."); - recorder.start().expect("Failed to start audio recording"); + let mut frame_buffer = vec![0; porcupine.frame_length() as usize]; + recorder::FRAME_LENGTH.store(porcupine.frame_length(), Ordering::SeqCst); + recorder::start_recording(); LISTENING.store(true, Ordering::SeqCst); - // Greet user - events::play("run", &app_handle); + // run start callback + start_callback(app_handle); // Listen until stop flag will be true - let mut frame_buffer = vec![0; porcupine.frame_length() as usize]; while !STOP_LISTENING.load(Ordering::SeqCst) { - recorder - .read(&mut frame_buffer) - .expect("Failed to read audio frame"); + recorder::read_microphone(&mut frame_buffer); if let Ok(keyword_index) = porcupine.process(&frame_buffer) { if keyword_index >= 0 { - println!("Yes, sir! {}", keyword_index); - events::play( - config::ASSISTANT_GREET_PHRASES - .choose(&mut rand::thread_rng()) - .unwrap(), - &app_handle, - ); - start = SystemTime::now(); - - app_handle - .emit_all(events::EventTypes::AssistantGreet.get(), ()) - .unwrap(); - - loop { - recorder - .read(&mut frame_buffer) - .expect("Failed to read audio frame"); - - // vosk part (partials included) - if let Some(mut test) = vosk::recognize(&frame_buffer) { - if !test.is_empty() { - println!("Recognized: {}", test); - - // some filtration - test = test.to_lowercase(); - for tbr in config::ASSISTANT_PHRASES_TBR { - test = test.replace(tbr, ""); - } - - // infer command - if let Some((cmd_path, cmd_config)) = - assistant_commands::fetch_command(&test, &COMMANDS) - { - println!("Recognized (filtered): {}", test); - println!("Command found: {:?}", cmd_path); - println!("Executing ..."); - - let cmd_result = assistant_commands::execute_command( - &cmd_path, - &cmd_config, - &app_handle, - ); - - match cmd_result { - Ok(_) => { - println!("Command executed successfully!"); - start = SystemTime::now(); // listen for more commands - continue; - } - Err(error_message) => { - println!("Error executing command: {}", error_message); - } - } - - app_handle - .emit_all(events::EventTypes::AssistantWaiting.get(), ()) - .unwrap(); - break; // return to picovoice after command execution (no matter successfull or not) - } - } - } - - match start.elapsed() { - Ok(elapsed) if elapsed > config::CMS_WAIT_DELAY => { - // return to picovoice after N seconds - app_handle - .emit_all(events::EventTypes::AssistantWaiting.get(), ()) - .unwrap(); - break; - } - _ => (), - } - } + // println!("Yes, sir! {}", keyword_index); + keyword_callback(&app_handle, keyword_index); } } } // Stop listening - println!("Stop listening ..."); - recorder.stop().expect("Failed to stop audio recording"); + recorder::stop_recording(); LISTENING.store(false, Ordering::SeqCst); STOP_LISTENING.store(false, Ordering::SeqCst); diff --git a/src-tauri/src/tauri_commands/sys.rs b/src-tauri/src/tauri_commands/sys.rs index cadb473..e44ab5a 100644 --- a/src-tauri/src/tauri_commands/sys.rs +++ b/src-tauri/src/tauri_commands/sys.rs @@ -6,7 +6,7 @@ static PEAK_ALLOC: PeakAlloc = PeakAlloc; extern crate systemstat; use std::thread; use std::time::Duration; -use systemstat::{saturating_sub_bytes, Platform, System}; +use systemstat::{Platform, System}; lazy_static! { static ref SYS: System = System::new(); diff --git a/src-tauri/src/vosk.rs b/src-tauri/src/vosk.rs index 91edef0..fd84224 100644 --- a/src-tauri/src/vosk.rs +++ b/src-tauri/src/vosk.rs @@ -1,5 +1,5 @@ use std::sync::Mutex; -use vosk::{CompleteResult, DecodingState, Model, Recognizer}; +use vosk::{DecodingState, Model, Recognizer}; use crate::config::VOSK_MODEL_PATH; @@ -46,13 +46,13 @@ pub fn recognize(data: &[i16]) -> Option { } } -pub fn stereo_to_mono(input_data: &[i16]) -> Vec { - let mut result = Vec::with_capacity(input_data.len() / 2); - result.extend( - input_data - .chunks_exact(2) - .map(|chunk| chunk[0] / 2 + chunk[1] / 2), - ); +// pub fn stereo_to_mono(input_data: &[i16]) -> Vec { +// let mut result = Vec::with_capacity(input_data.len() / 2); +// result.extend( +// input_data +// .chunks_exact(2) +// .map(|chunk| chunk[0] / 2 + chunk[1] / 2), +// ); - result -} +// result +// } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 75a28a6..6b6559f 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "jarvis-app", - "version": "0.0.0" + "version": "0.0.1" }, "tauri": { "allowlist": { @@ -45,7 +45,7 @@ "libstdc++-6.dll", "libwinpthread-1.dll", "libgcc_s_seh-1.dll", - "libpv_recorder.dll" + "libvosk.lib" ] }, "security": { diff --git a/src-tauri/vosk/libgcc_s_seh-1.dll b/src-tauri/vosk/libgcc_s_seh-1.dll deleted file mode 100644 index 6e75249..0000000 Binary files a/src-tauri/vosk/libgcc_s_seh-1.dll and /dev/null differ diff --git a/src-tauri/vosk/libstdc++-6.dll b/src-tauri/vosk/libstdc++-6.dll deleted file mode 100644 index 7783d88..0000000 Binary files a/src-tauri/vosk/libstdc++-6.dll and /dev/null differ diff --git a/src-tauri/vosk/libvosk.dll b/src-tauri/vosk/libvosk.dll deleted file mode 100644 index 4f3c6ed..0000000 Binary files a/src-tauri/vosk/libvosk.dll and /dev/null differ diff --git a/src-tauri/vosk/libwinpthread-1.dll b/src-tauri/vosk/libwinpthread-1.dll deleted file mode 100644 index 0b416a5..0000000 Binary files a/src-tauri/vosk/libwinpthread-1.dll and /dev/null differ diff --git a/src-tauri/vosk/vosk_api.h b/src-tauri/vosk/vosk_api.h deleted file mode 100644 index 9816019..0000000 --- a/src-tauri/vosk/vosk_api.h +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright 2020-2021 Alpha Cephei Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* This header contains the C API for Vosk speech recognition system */ - -#ifndef VOSK_API_H -#define VOSK_API_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** Model stores all the data required for recognition - * it contains static data and can be shared across processing - * threads. */ -typedef struct VoskModel VoskModel; - - -/** Speaker model is the same as model but contains the data - * for speaker identification. */ -typedef struct VoskSpkModel VoskSpkModel; - - -/** Recognizer object is the main object which processes data. - * Each recognizer usually runs in own thread and takes audio as input. - * Once audio is processed recognizer returns JSON object as a string - * which represent decoded information - words, confidences, times, n-best lists, - * speaker information and so on */ -typedef struct VoskRecognizer VoskRecognizer; - - -/** - * Batch model object - */ -typedef struct VoskBatchModel VoskBatchModel; - -/** - * Batch recognizer object - */ -typedef struct VoskBatchRecognizer VoskBatchRecognizer; - - -/** Loads model data from the file and returns the model object - * - * @param model_path: the path of the model on the filesystem - * @returns model object or NULL if problem occured */ -VoskModel *vosk_model_new(const char *model_path); - - -/** Releases the model memory - * - * The model object is reference-counted so if some recognizer - * depends on this model, model might still stay alive. When - * last recognizer is released, model will be released too. */ -void vosk_model_free(VoskModel *model); - - -/** Check if a word can be recognized by the model - * @param word: the word - * @returns the word symbol if @param word exists inside the model - * or -1 otherwise. - * Reminding that word symbol 0 is for */ -int vosk_model_find_word(VoskModel *model, const char *word); - - -/** Loads speaker model data from the file and returns the model object - * - * @param model_path: the path of the model on the filesystem - * @returns model object or NULL if problem occured */ -VoskSpkModel *vosk_spk_model_new(const char *model_path); - - -/** Releases the model memory - * - * The model object is reference-counted so if some recognizer - * depends on this model, model might still stay alive. When - * last recognizer is released, model will be released too. */ -void vosk_spk_model_free(VoskSpkModel *model); - -/** Creates the recognizer object - * - * The recognizers process the speech and return text using shared model data - * @param model VoskModel containing static data for recognizer. Model can be - * shared across recognizers, even running in different threads. - * @param sample_rate The sample rate of the audio you going to feed into the recognizer. - * Make sure this rate matches the audio content, it is a common - * issue causing accuracy problems. - * @returns recognizer object or NULL if problem occured */ -VoskRecognizer *vosk_recognizer_new(VoskModel *model, float sample_rate); - - -/** Creates the recognizer object with speaker recognition - * - * With the speaker recognition mode the recognizer not just recognize - * text but also return speaker vectors one can use for speaker identification - * - * @param model VoskModel containing static data for recognizer. Model can be - * shared across recognizers, even running in different threads. - * @param sample_rate The sample rate of the audio you going to feed into the recognizer. - * Make sure this rate matches the audio content, it is a common - * issue causing accuracy problems. - * @param spk_model speaker model for speaker identification - * @returns recognizer object or NULL if problem occured */ -VoskRecognizer *vosk_recognizer_new_spk(VoskModel *model, float sample_rate, VoskSpkModel *spk_model); - - -/** Creates the recognizer object with the phrase list - * - * Sometimes when you want to improve recognition accuracy and when you don't need - * to recognize large vocabulary you can specify a list of phrases to recognize. This - * will improve recognizer speed and accuracy but might return [unk] if user said - * something different. - * - * Only recognizers with lookahead models support this type of quick configuration. - * Precompiled HCLG graph models are not supported. - * - * @param model VoskModel containing static data for recognizer. Model can be - * shared across recognizers, even running in different threads. - * @param sample_rate The sample rate of the audio you going to feed into the recognizer. - * Make sure this rate matches the audio content, it is a common - * issue causing accuracy problems. - * @param grammar The string with the list of phrases to recognize as JSON array of strings, - * for example "["one two three four five", "[unk]"]". - * - * @returns recognizer object or NULL if problem occured */ -VoskRecognizer *vosk_recognizer_new_grm(VoskModel *model, float sample_rate, const char *grammar); - - -/** Adds speaker model to already initialized recognizer - * - * Can add speaker recognition model to already created recognizer. Helps to initialize - * speaker recognition for grammar-based recognizer. - * - * @param spk_model Speaker recognition model */ -void vosk_recognizer_set_spk_model(VoskRecognizer *recognizer, VoskSpkModel *spk_model); - - -/** Reconfigures recognizer to use grammar - * - * @param recognizer Already running VoskRecognizer - * @param grammar Set of phrases in JSON array of strings or "[]" to use default model graph. - * See also vosk_recognizer_new_grm - */ -void vosk_recognizer_set_grm(VoskRecognizer *recognizer, char const *grammar); - - -/** Configures recognizer to output n-best results - * - *
- *   {
- *      "alternatives": [
- *          { "text": "one two three four five", "confidence": 0.97 },
- *          { "text": "one two three for five", "confidence": 0.03 },
- *      ]
- *   }
- * 
- * - * @param max_alternatives - maximum alternatives to return from recognition results - */ -void vosk_recognizer_set_max_alternatives(VoskRecognizer *recognizer, int max_alternatives); - - -/** Enables words with times in the output - * - *
- *   "result" : [{
- *       "conf" : 1.000000,
- *       "end" : 1.110000,
- *       "start" : 0.870000,
- *       "word" : "what"
- *     }, {
- *       "conf" : 1.000000,
- *       "end" : 1.530000,
- *       "start" : 1.110000,
- *       "word" : "zero"
- *     }, {
- *       "conf" : 1.000000,
- *       "end" : 1.950000,
- *       "start" : 1.530000,
- *       "word" : "zero"
- *     }, {
- *       "conf" : 1.000000,
- *       "end" : 2.340000,
- *       "start" : 1.950000,
- *       "word" : "zero"
- *     }, {
- *       "conf" : 1.000000,
- *       "end" : 2.610000,
- *       "start" : 2.340000,
- *       "word" : "one"
- *     }],
- * 
- * - * @param words - boolean value - */ -void vosk_recognizer_set_words(VoskRecognizer *recognizer, int words); - -/** Like above return words and confidences in partial results - * - * @param partial_words - boolean value - */ -void vosk_recognizer_set_partial_words(VoskRecognizer *recognizer, int partial_words); - -/** Set NLSML output - * @param nlsml - boolean value - */ -void vosk_recognizer_set_nlsml(VoskRecognizer *recognizer, int nlsml); - - -/** Accept voice data - * - * accept and process new chunk of voice data - * - * @param data - audio data in PCM 16-bit mono format - * @param length - length of the audio data - * @returns 1 if silence is occured and you can retrieve a new utterance with result method - * 0 if decoding continues - * -1 if exception occured */ -int vosk_recognizer_accept_waveform(VoskRecognizer *recognizer, const char *data, int length); - - -/** Same as above but the version with the short data for language bindings where you have - * audio as array of shorts */ -int vosk_recognizer_accept_waveform_s(VoskRecognizer *recognizer, const short *data, int length); - - -/** Same as above but the version with the float data for language bindings where you have - * audio as array of floats */ -int vosk_recognizer_accept_waveform_f(VoskRecognizer *recognizer, const float *data, int length); - - -/** Returns speech recognition result - * - * @returns the result in JSON format which contains decoded line, decoded - * words, times in seconds and confidences. You can parse this result - * with any json parser - * - *
- *  {
- *    "text" : "what zero zero zero one"
- *  }
- * 
- * - * If alternatives enabled it returns result with alternatives, see also vosk_recognizer_set_max_alternatives(). - * - * If word times enabled returns word time, see also vosk_recognizer_set_word_times(). - */ -const char *vosk_recognizer_result(VoskRecognizer *recognizer); - - -/** Returns partial speech recognition - * - * @returns partial speech recognition text which is not yet finalized. - * result may change as recognizer process more data. - * - *
- * {
- *    "partial" : "cyril one eight zero"
- * }
- * 
- */ -const char *vosk_recognizer_partial_result(VoskRecognizer *recognizer); - - -/** Returns speech recognition result. Same as result, but doesn't wait for silence - * You usually call it in the end of the stream to get final bits of audio. It - * flushes the feature pipeline, so all remaining audio chunks got processed. - * - * @returns speech result in JSON format. - */ -const char *vosk_recognizer_final_result(VoskRecognizer *recognizer); - - -/** Resets the recognizer - * - * Resets current results so the recognition can continue from scratch */ -void vosk_recognizer_reset(VoskRecognizer *recognizer); - - -/** Releases recognizer object - * - * Underlying model is also unreferenced and if needed released */ -void vosk_recognizer_free(VoskRecognizer *recognizer); - -/** Set log level for Kaldi messages - * - * @param log_level the level - * 0 - default value to print info and error messages but no debug - * less than 0 - don't print info messages - * greather than 0 - more verbose mode - */ -void vosk_set_log_level(int log_level); - -/** - * Init, automatically select a CUDA device and allow multithreading. - * Must be called once from the main thread. - * Has no effect if HAVE_CUDA flag is not set. - */ -void vosk_gpu_init(); - -/** - * Init CUDA device in a multi-threaded environment. - * Must be called for each thread. - * Has no effect if HAVE_CUDA flag is not set. - */ -void vosk_gpu_thread_init(); - -/** Creates the batch recognizer object - * - * @returns model object or NULL if problem occured */ -VoskBatchModel *vosk_batch_model_new(const char *model_path); - -/** Releases batch model object */ -void vosk_batch_model_free(VoskBatchModel *model); - -/** Wait for the processing */ -void vosk_batch_model_wait(VoskBatchModel *model); - -/** Creates batch recognizer object - * @returns recognizer object or NULL if problem occured */ -VoskBatchRecognizer *vosk_batch_recognizer_new(VoskBatchModel *model, float sample_rate); - -/** Releases batch recognizer object */ -void vosk_batch_recognizer_free(VoskBatchRecognizer *recognizer); - -/** Accept batch voice data */ -void vosk_batch_recognizer_accept_waveform(VoskBatchRecognizer *recognizer, const char *data, int length); - -/** Set NLSML output - * @param nlsml - boolean value - */ -void vosk_batch_recognizer_set_nlsml(VoskBatchRecognizer *recognizer, int nlsml); - -/** Closes the stream */ -void vosk_batch_recognizer_finish_stream(VoskBatchRecognizer *recognizer); - -/** Return results */ -const char *vosk_batch_recognizer_front_result(VoskBatchRecognizer *recognizer); - -/** Release and free first retrieved result */ -void vosk_batch_recognizer_pop(VoskBatchRecognizer *recognizer); - -/** Get amount of pending chunks for more intelligent waiting */ -int vosk_batch_recognizer_get_pending_chunks(VoskBatchRecognizer *recognizer); - -#ifdef __cplusplus -} -#endif - -#endif /* VOSK_API_H */ diff --git a/src/components/Header.svelte b/src/components/Header.svelte index a9be6e7..c92d749 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -13,10 +13,10 @@