Skip to content

Add more tutorial in the guide book #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions doc/g_flite_app_split_input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Split the input
62 changes: 62 additions & 0 deletions doc/g_flite_apps_logic.md
Original file line number Diff line number Diff line change
@@ -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<String> {
unimplemented!()
}

fn run_on_golem(chunks: Vec<String>) -> ComputedTask {
unimplemented!()
}

fn combine_output(computed_task: ComputedTask) -> Vec<u8> {
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();
}
```
23 changes: 23 additions & 0 deletions doc/g_flite_intro.md
Original file line number Diff line number Diff line change
@@ -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/
45 changes: 45 additions & 0 deletions doc/g_flite_setup.md
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>"]
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
32 changes: 32 additions & 0 deletions doc/g_flite_wasm.md
Original file line number Diff line number Diff line change
@@ -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