From b3e2ada53b66a6a24abec2cb77102490424acff6 Mon Sep 17 00:00:00 2001 From: Gabriel Tofvesson Date: Sat, 18 Mar 2023 17:09:27 +0100 Subject: [PATCH] Implement simple voice_in->chat->voice_out system --- Cargo.lock | 567 ++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- input_prompt.mp3 | Bin 0 -> 28212 bytes src/main.rs | 84 ++++++- 4 files changed, 647 insertions(+), 8 deletions(-) create mode 100644 input_prompt.mp3 diff --git a/Cargo.lock b/Cargo.lock index b43230a..152a21a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,12 +20,40 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "alsa" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8512c9117059663fb5606788fbca3619e2a91dac0e3fe516242eab1fa6be5e44" +dependencies = [ + "alsa-sys", + "bitflags", + "libc", + "nix", +] + +[[package]] +name = "alsa-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "anyhow" version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "autocfg" version = "1.1.0" @@ -44,6 +72,26 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bindgen" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a022e58a142a46fea340d68012b9201c094e93ec3d033a944a24f8fd4a4f09a" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -65,6 +113,12 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + [[package]] name = "byteorder" version = "1.4.3" @@ -107,6 +161,21 @@ dependencies = [ "jobserver", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -122,6 +191,33 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clang-sys" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "claxon" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -134,16 +230,67 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys", + "core-foundation-sys 0.8.3", "libc", ] +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + [[package]] name = "core-foundation-sys" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "coreaudio-rs" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb17e2d1795b1996419648915df94bc7103c28f7b48062d7acf4652fc371b2ff" +dependencies = [ + "bitflags", + "core-foundation-sys 0.6.2", + "coreaudio-sys", +] + +[[package]] +name = "coreaudio-sys" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9444b94b8024feecc29e01a9706c69c1e26bfee480221c90764200cfd778fb" +dependencies = [ + "bindgen", +] + +[[package]] +name = "cpal" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1241019dec4a73f874bdf6fe3467a8478b47cecaf79435f7acb01f107ab41b1" +dependencies = [ + "alsa", + "core-foundation-sys 0.8.3", + "coreaudio-rs", + "dasp_sample", + "jni 0.19.0", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "oboe", + "once_cell", + "parking_lot", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + [[package]] name = "cpufeatures" version = "0.2.5" @@ -216,6 +363,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "derive_builder" version = "0.12.0" @@ -419,6 +572,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.3.16" @@ -468,6 +627,12 @@ dependencies = [ "digest", ] +[[package]] +name = "hound" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d13cdbd5dbb29f9c88095bbdc2590c9cba0d0a1269b983fef6b2cdd7e9f4db1" + [[package]] name = "http" version = "0.2.9" @@ -597,6 +762,40 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.26" @@ -621,12 +820,39 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lewton" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030" +dependencies = [ + "byteorder", + "ogg", + "tinyvec", +] + [[package]] name = "libc" version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -652,6 +878,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "mach2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.5.0" @@ -674,6 +909,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.6.2" @@ -713,6 +954,76 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" @@ -723,6 +1034,59 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "oboe" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" +dependencies = [ + "jni 0.20.0", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "oboe-sys", +] + +[[package]] +name = "oboe-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f44155e7fb718d3cfddcf70690b2b51ac4412f347cd9e4fbe511abe9cd7b5f2" +dependencies = [ + "cc", +] + +[[package]] +name = "ogg" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6951b4e8bf21c8193da321bcce9c9dd2e13c858fe078bf9054a288b419ae5d6e" +dependencies = [ + "byteorder", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -842,6 +1206,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.2.0" @@ -866,6 +1236,16 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.52" @@ -890,6 +1270,12 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "raw-window-handle" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f851a03551ceefd30132e447f07f96cb7011d6b658374f3aed847333adb5559" + [[package]] name = "redox_syscall" version = "0.2.16" @@ -899,6 +1285,21 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + [[package]] name = "reqwest" version = "0.11.14" @@ -939,6 +1340,25 @@ dependencies = [ "winreg", ] +[[package]] +name = "rodio" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf1d4dea18dff2e9eb6dca123724f8b60ef44ad74a9ad283cdfe025df7e73fa" +dependencies = [ + "claxon", + "cpal", + "hound", + "lewton", + "symphonia", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.36.9" @@ -959,6 +1379,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.21" @@ -982,7 +1411,7 @@ checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", - "core-foundation-sys", + "core-foundation-sys 0.8.3", "libc", "security-framework-sys", ] @@ -993,7 +1422,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ - "core-foundation-sys", + "core-foundation-sys 0.8.3", "libc", ] @@ -1062,6 +1491,12 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1108,6 +1543,56 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "symphonia" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3671dd6f64f4f9d5c87179525054cfc1f60de23ba1f193bd6ceab812737403f1" +dependencies = [ + "lazy_static", + "symphonia-bundle-mp3", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-bundle-mp3" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a0846e7a2c9a8081ff799fc83a975170417ad2a143f644a77ec2e3e82a2b73" +dependencies = [ + "bitflags", + "lazy_static", + "log", + "symphonia-core", + "symphonia-metadata", +] + +[[package]] +name = "symphonia-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869" +dependencies = [ + "arrayvec", + "bitflags", + "bytemuck", + "lazy_static", + "log", +] + +[[package]] +name = "symphonia-metadata" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acd35c263223ef6161000be79b124a75de3e065eea563bf3ef169b3e94c7bb2e" +dependencies = [ + "encoding_rs", + "lazy_static", + "log", + "symphonia-core", +] + [[package]] name = "syn" version = "1.0.109" @@ -1143,6 +1628,26 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.0", +] + [[package]] name = "time" version = "0.3.20" @@ -1229,6 +1734,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" + +[[package]] +name = "toml_edit" +version = "0.19.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -1327,6 +1849,18 @@ dependencies = [ "anyhow", "elevenlabs_rs", "openai_rs", + "rodio", + "tokio", +] + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", ] [[package]] @@ -1450,12 +1984,30 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -1537,6 +2089,15 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "winnow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index 262762c..506e5d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,6 @@ edition = "2021" [dependencies] anyhow = "1.0.70" openai_rs = { path = "./OpenAI-Rust" } -elevenlabs_rs = { path = "./elevenlabs-api-rust" } \ No newline at end of file +elevenlabs_rs = { path = "./elevenlabs-api-rust" } +tokio = "1.26.0" +rodio = "0.17.1" diff --git a/input_prompt.mp3 b/input_prompt.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..4407c8f58d0ebd2843e90e45338557bb8e9756ae GIT binary patch literal 28212 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 anyhow::Result { Ok(std::fs::read_to_string(std::path::Path::new(name))?.trim().to_string()) @@ -13,6 +14,81 @@ fn get_elevenlabs() -> anyhow::Result { Ok(ElevenLabsAPI::new(get_file("elevenlabs.key")?)) } -fn main() { - println!("Hello, world!"); +const VOICE_ID: &str = "u339B6b9cariBZ7Vw3q4"; +const INPUT_FILE: &str = "input_prompt.mp3"; + +async fn transform_prompt(openai: &Context, prompt: File) -> anyhow::Result { + Ok(openai.create_transcription(TranscriptionRequestBuilder::default().model("whisper-1").file(AudioFile::MP3(prompt)).build()?).await?.text) +} + +async fn generate_response(openai: &Context, elevenlabs: &ElevenLabsAPI, history: &mut Vec) { + let response = openai.create_chat_completion( + ChatHistoryBuilder::default() + .messages(history.clone()) + .model("gpt-3.5-turbo") + .build() + .unwrap() + ).await; + + if let Ok(mut response) = response { + let response = response.choices.remove(0).message; + let tts = elevenlabs.generate_tts(VOICE_ID.to_owned(), TTSMessage::new(response.content.clone(), VoiceSettings { + stability: 0.5, + similarity_boost: 0.75, + })); + history.push(response); + + let tts = tts.await; + if let Ok(tts) = tts { + File::create("response.wav").await.unwrap().write_all(tts.audio()[0].as_slice()).await.unwrap(); + } else { + println!("{:?}", tts); + } + } else { + println!("{:?}", response); + } + let response = openai.create_chat_completion( + ChatHistoryBuilder::default() + .messages(history.clone()) + .model("gpt-3.5-turbo") + .build() + .unwrap() + ).await; + + if let Ok(mut response) = response { + let response = response.choices.remove(0).message; + let tts = elevenlabs.generate_tts(VOICE_ID.to_owned(), TTSMessage::new(response.content.clone(), VoiceSettings { + stability: 0.5, + similarity_boost: 0.75, + })); + history.push(response); + + let tts = tts.await; + if let Ok(tts) = tts { + File::create("response.wav").await.unwrap().write_all(tts.audio()[0].as_slice()).await.unwrap(); + } else { + println!("{:?}", tts); + } + } else { + println!("{:?}", response); + } +} + +#[tokio::main] +async fn main() { + let openai = get_openai().unwrap(); + let elevenlabs = get_elevenlabs().unwrap(); + + // Start of chat + let mut history: Vec = Vec::new(); + history.push(ChatMessage::new(Role::System, "You are a voice assistant; Give helpful, accurate and concise responses. Your name is Jarvis. You are currently only capable of responding to prompts.")); + + let response = transform_prompt(&openai, File::open(INPUT_FILE).await.unwrap()).await; + + if let Ok(response) = response { + history.push(ChatMessage::new(Role::User, response)); + generate_response(&openai, &elevenlabs, &mut history).await; + } else { + println!("{:?}", response); + } }