diff --git a/Cargo.toml b/Cargo.toml index 8baea42..cdc21f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,11 @@ serde_json = "1.0" [build-dependencies] bindgen = "0.54" cc = { version = "1.0", features = ["parallel"] } +flate2 = "1.0.17" +tar = "0.4.29" +curl = "0.4.33" +anyhow = "1.0.32" +reqwest = {version = "0.10.7", features = ["blocking"]} [dev-dependencies] audrey = "0.2" diff --git a/build.rs b/build.rs index fa42bd4..f0623a9 100644 --- a/build.rs +++ b/build.rs @@ -1,19 +1,64 @@ -use std::{env, fs}; -use std::path::PathBuf; +use std::{env, fs, io}; +use std::path::{Path, PathBuf}; use std::process::Command; +use flate2::read::GzDecoder; +use tar::Archive; +use curl::easy::Easy; +use std::io::Write; +const OPENFST_SRC: &str = "http://www.openfst.org/twiki/pub/FST/FstDownload/openfst-1.6.7.tar.gz"; + + +fn download>(source_url: &str, target_file: P) -> anyhow::Result<()> { + let f = fs::File::create(&target_file)?; + let mut writer = io::BufWriter::new(f); + let mut easy = Easy::new(); + easy.useragent("Curl Download")?; + easy.url(source_url)?; + easy.write_function(move |data| Ok(writer.write(data).unwrap()))?; + easy.perform()?; + + let response_code = easy.response_code()?; + if response_code == 200 { + Ok(()) + } else { + Err(anyhow::anyhow!( + "Unexpected response code {} for {}", + response_code, + source_url + )) + } +} + +fn extract, P2: AsRef>(filename: P1, outpath: P2) -> anyhow::Result<()> { + let file = fs::File::open(&filename)?; + let tar = GzDecoder::new(file); + let mut archive = Archive::new(tar); + archive.unpack(outpath.as_ref())?; + + Ok(()) +} fn main() { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + println!("cargo:rerun-if-changed=cbits/vosk.h"); println!("cargo:rerun-if-changed=build.rs"); + let openfst_name = out_path.join("openfst.tar.gz"); + let openfst_dir = out_path.join("openfst-1.6.7"); + if !openfst_dir.exists() { + download(OPENFST_SRC, &openfst_name).unwrap(); + extract(openfst_name, &out_path).unwrap(); + } + let bindings = bindgen::Builder::default() .generate_inline_functions(true) .derive_default(false) .header("cbits/vosk.h") .clang_arg("-I./resources/vosk-api/src/") .clang_arg("-I./resources/kaldi/src/") - .clang_arg("-I./resources/openfst/src/include") + .clang_arg(format!("-I{}", openfst_dir.join("src/include").to_string_lossy())) .clang_arg("-std=c++14") .clang_arg("-x") .clang_arg("c++") @@ -28,7 +73,6 @@ fn main() { .generate() .expect("Unable to generate bindings"); - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); @@ -38,19 +82,19 @@ fn main() { .extra_warnings(false) .static_flag(true) .cpp(true) - .include("resources/openfst/src/include") - .file("resources/openfst/src/lib/compat.cc") - .file("resources/openfst/src/lib/encode.cc") - .file("resources/openfst/src/lib/fst-types.cc") - .file("resources/openfst/src/lib/fst.cc") - .file("resources/openfst/src/lib/mapped-file.cc") - .file("resources/openfst/src/lib/properties.cc") - .file("resources/openfst/src/lib/symbol-table-ops.cc") - .file("resources/openfst/src/lib/symbol-table.cc") - .file("resources/openfst/src/lib/util.cc") - .file("resources/openfst/src/lib/weight.cc") - .file("resources/openfst/src/extensions/ngram/bitmap-index.cc") - .file("resources/openfst/src/extensions/ngram/nthbit.cc") + .include(openfst_dir.join("src/include")) + .file(openfst_dir.join("src/lib/compat.cc")) + .file(openfst_dir.join("src/lib/flags.cc")) + .file(openfst_dir.join("src/lib/fst-types.cc")) + .file(openfst_dir.join("src/lib/fst.cc")) + .file(openfst_dir.join("src/lib/mapped-file.cc")) + .file(openfst_dir.join("src/lib/properties.cc")) + .file(openfst_dir.join("src/lib/symbol-table-ops.cc")) + .file(openfst_dir.join("src/lib/symbol-table.cc")) + .file(openfst_dir.join("src/lib/util.cc")) + .file(openfst_dir.join("src/lib/weight.cc")) + .file(openfst_dir.join("src/extensions/ngram/bitmap-index.cc")) + .file(openfst_dir.join("src/extensions/ngram/nthbit.cc")) .try_compile("libopenfst") .unwrap(); @@ -61,7 +105,7 @@ fn main() { .cpp(true) .include("resources/vosk-api/src") .include("resources/kaldi/src/") - .include("resources/openfst/src/include") + .include(openfst_dir.join("src/include")) .file("resources/vosk-api/src/kaldi_recognizer.cc") .file("resources/vosk-api/src/model.cc") .file("resources/vosk-api/src/spk_model.cc") @@ -69,15 +113,6 @@ fn main() { .try_compile("libvosk") .unwrap(); - let out_dir = env::var("OUT_DIR").unwrap(); - let contents = fs::read_to_string("resources/kaldi/src/lat/kaldi-lattice.cc").expect("Something went wrong reading the file"); - - let contents = contents.replace("printer.Print(&os, \"\");", "printer.Print(os, \"\");"); - - let kaldi_lattice = format!("{}/kaldi-lattice.cc", out_dir); - fs::write(&kaldi_lattice, contents).expect("Write file!"); - - Command::new("sh") .arg("-c") .arg("resources/kaldi/src/base/get_version.sh") @@ -91,7 +126,7 @@ fn main() { .cpp(true) .define("HAVE_OPENBLAS", "true") - .include("resources/openfst/src/include") + .include(openfst_dir.join("src/include")) .include("resources/kaldi/src") // base @@ -242,7 +277,7 @@ fn main() { // .file("resources/kaldi/src/lat/compose-lattice-pruned.cc") // .file("resources/kaldi/src/lat/confidence.cc") .file("resources/kaldi/src/lat/determinize-lattice-pruned.cc") - .file(&kaldi_lattice) // .file("resources/kaldi/src/lat/kaldi-lattice.cc") + .file("resources/kaldi/src/lat/kaldi-lattice.cc") // .file("resources/kaldi/src/lat/kaldi-lattice.cc") .file("resources/kaldi/src/lat/lattice-functions.cc") // .file("resources/kaldi/src/lat/phone-align-lattice.cc") .file("resources/kaldi/src/lat/push-lattice.cc") diff --git a/resources/openfst b/resources/openfst deleted file mode 160000 index 256f83e..0000000 --- a/resources/openfst +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 256f83e52112a5cd37e37a34beff2c4f0eae4660 diff --git a/src/session.rs b/src/session.rs index d50dcf7..5ba0857 100644 --- a/src/session.rs +++ b/src/session.rs @@ -89,7 +89,7 @@ impl VoskSession { // VoskSession { // inner: ffi::KaldiRecognizer::new1(model as *mut ffi::Model, cfg.freq) // } - } else if let Some(grammar) = &cfg.grammar { + } else if let Some(_grammar) = &cfg.grammar { unimplemented!() // VoskSession { // inner: unsafe { ffi::KaldiRecognizer::new2(model as *mut ffi::Model, cfg.freq, grammar.as_c_str().as_ptr()) }