diff --git a/doc/SUMMARY.md b/doc/SUMMARY.md index 2a2f8c9..2c99792 100644 --- a/doc/SUMMARY.md +++ b/doc/SUMMARY.md @@ -1,4 +1,9 @@ # Summary - [Introduction](./index.md) +- [g-flite: step-by-step](./g_flite_intro.md) + - [Set up Cargo](./g_flite_setup.md) + - [Compile flite to Wasm](./g_flite_wasm.md) + - [Write the app's logic](./g_flite_apps_logic.md) + - [Split the input](./g_flite_app_split_input.md) - [API documentation](./api_docs.md) diff --git a/doc/g_flite_app_split_input.md b/doc/g_flite_app_split_input.md new file mode 100644 index 0000000..5fb02c1 --- /dev/null +++ b/doc/g_flite_app_split_input.md @@ -0,0 +1 @@ +# Split the input diff --git a/doc/g_flite_apps_logic.md b/doc/g_flite_apps_logic.md new file mode 100644 index 0000000..815629a --- /dev/null +++ b/doc/g_flite_apps_logic.md @@ -0,0 +1,62 @@ +# Write the app's logic + +The app will consist of 3 bits of functionality which will be executed sequentially: +1. splitting the input text into smaller chunks, +2. packaging each chunk and the `flite` Wasm binary into a `gWasm` task and executing + it on the Golem Network, and +3. collecting the resultant WAV files and combining them into one final WAV file. + +In this tutorial, we will go ahead and implement everything using only the `main.rs` +module. If you were writing a real app (and especially one that is more complicated +than this one, you'd probably want to split the app's functionality into a number of +different modules). We will also specifically not propagate any errors and instead +panic on each (you don't want to do that in your real app). + +Fire up your favourite editor and open `src/main.rs`. + +## src/main.rs + +```rust +use gwasm_api::prelude::*; +use std::{env, fs, process}; + +fn split_input(text: String) -> Vec { + unimplemented!() +} + +fn run_on_golem(chunks: Vec) -> ComputedTask { + unimplemented!() +} + +fn combine_output(computed_task: ComputedTask) -> Vec { + unimplemented!() +} + +const FLITE_JS: &[u8] = include_bytes!("../assets/flite.js"); +const FLITE_WASM: &[u8] = include_bytes!("../assets/flite.wasm"); + +fn main() { + // Read in the input text file + let filename = if let Some(filename) = env::args().nth(1) { + filename + } else { + eprintln!("No input file specified!"); + process::exit(1); + }; + + let contents = fs::read(filename).unwrap(); + let text = String::from_utf8(contents).unwrap(); + + // Split the input + let chunks = split_input(text); + + // Run on Golem using gwasm-api + let computed_task = run_on_golem(chunks); + + // Combine the output + let output_wav = combine_output(computed_task); + + // Write to file + fs::write("output.wav", output_wav).unwrap(); +} +``` diff --git a/doc/g_flite_intro.md b/doc/g_flite_intro.md new file mode 100644 index 0000000..b15af93 --- /dev/null +++ b/doc/g_flite_intro.md @@ -0,0 +1,23 @@ +# g-flite: step-by-step + +In this tutorial, we will build a minimalistic version of [g-flite] app, +fully functional, albeit devoid of unnecessary features such as animated +progressbar. + +The idea behind the app is very simple: we want to run the [flite] text-to-speech +program, compiled to Wasm (currently, gWasm requires apps to target `wasm32-unknown-emscripten` +target), distributed across the Golem Network. Thus, given a text input, our app +needs to: +1. package the Wasm binary +2. split the input into some nonoverlapping chunks of text for processing with each + chunk processed in parallel by some Golem node +3. prepare a gWasm task using `gwasm-api`, and send it to our Golem instance for + distributing across the Golem Network +4. and finally, combine the resultant WAV chunks into one final WAV which represents + our input text converted to speech + +The step 3. described above is the one where we will interface with `gwasm-api` crate, +and this is the step where we can orchestrate progress updates to the user. + +[g-flite]: https://github.com/golemfactory/g-flite +[flite]: http://www.festvox.org/flite/ diff --git a/doc/g_flite_setup.md b/doc/g_flite_setup.md new file mode 100644 index 0000000..12abdb4 --- /dev/null +++ b/doc/g_flite_setup.md @@ -0,0 +1,45 @@ +# Set up Cargo + +In this tutorial, we will be building an app, so go ahead and create +a Rust executable by running: + +``` +cargo new --bin g-flite +``` + +Next, let us specify some dependencies ahead of time in `Cargo.toml`: + +``` +[package] +name = "g-flite" +version = "0.1.0" +authors = ["Jakub Konka "] +edition = 2018 + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +appdirs = "0.2" +gwasm-api = "0.1" +hound = { git = "https://github.com/kubkon/hound" } +openssl = "0.10" + +[features] +openssl_vendored = ["openssl/vendored"] +``` + +A few words of explanation are in order here: +* `gwasm-api` refers to this crate. +* We use the [hound] crate to handle concatenating of WAV files + which we expect after each gWasm subtask completes---note that we use + my fork of the crate since `flite` seems not to follow the WAV format + to the letter and hence I've had to introduce some tweaks to be able to + read and concatenate the resultant WAV files in one final file. +* Even though we don't make use of the [openssl] crate directly, we specify + it here, so that on Linux and macOS we can rely on prepackaged openssl lib; + on Windows, you'll need to install it by hand. You can find the [binaries here]. + +[appdirs]: https://github.com/djc/appdirs-rs +[hound]: https://github.com/kubkon/hound +[openssl]: https://github.com/sfackler/rust-openssl +[binaries here]: https://slproweb.com/products/Win32OpenSSL.html diff --git a/doc/g_flite_wasm.md b/doc/g_flite_wasm.md new file mode 100644 index 0000000..ec67e6f --- /dev/null +++ b/doc/g_flite_wasm.md @@ -0,0 +1,32 @@ +# Compile flite to Wasm + +We will not compile [flite] to Wasm ourselves. Instead, we will use already +precompiled binary. Go ahead and download the binary from [here]. You will +need both the JavaScript file and the Wasm binary: + +``` +# https://github.com/golemfactory/g-flite/tree/master/assets +.. +flite.js +flite.wasm +``` + +Download them and save them in the `assets` folder: + +``` +g-flite/ +| +|- assets/ +| | +| |- flite.js +| |- flite.wasm +| +|- src/ +| | +| |- main.rs +| +|- Cargo.toml +``` + +[flite]: http://www.festvox.org/flite/ +[here]: https://github.com/golemfactory/g-flite/tree/master/assets