Skip to content

Commit

Permalink
Merge pull request #72 from Picovoice/v1.2-rust
Browse files Browse the repository at this point in the history
V1.2 rust
  • Loading branch information
ErisMik committed Jul 13, 2023
2 parents 30c873e + 4a9e19f commit 8641b24
Show file tree
Hide file tree
Showing 13 changed files with 614 additions and 240 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/rust-codestyle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Rust Codestyle

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- '.github/workflows/rust-codestyle.yml'
- 'binding/rust/**/*.rs'
- 'demo/rust/**/*.rs'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '.github/workflows/rust-codestyle.yml'
- 'binding/rust/**/*.rs'
- 'demo/rust/**/*.rs'

env:
CARGO_TERM_COLOR: always

defaults:
run:
shell: bash

jobs:
check-rust-binding-codestyle:
runs-on: ubuntu-latest
defaults:
run:
working-directory: binding/rust

steps:
- uses: actions/checkout@v3

- name: Rust pre-build
run: bash copy.sh

- name: Rust dependencies
run: sudo apt install libasound2-dev -y

- name: Rust pre-build
run: bash copy.sh
working-directory: binding/rust

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Run clippy
run: cargo clippy -- -D warnings

check-rust-demo-codestyle:
runs-on: ubuntu-latest
defaults:
run:
working-directory: demo/rust

steps:
- uses: actions/checkout@v3

- name: Rust dependencies
run: sudo apt install libasound2-dev -y

- name: Rust pre-build
run: bash copy.sh
working-directory: binding/rust

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Run clippy
run: cargo clippy -- -D warnings
81 changes: 81 additions & 0 deletions .github/workflows/rust-demos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Rust Demos

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- '.github/workflows/rust-demos.yml'
- 'demo/rust/**'
- '!demo/rust/README.md'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '.github/workflows/rust-demos.yml'
- 'demo/rust/**'
- '!demo/rust/README.md'

env:
CARGO_TERM_COLOR: always

defaults:
run:
working-directory: demo/rust

jobs:
build-github-hosted:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]

steps:
- uses: actions/checkout@v3

- name: Rust dependencies
if: matrix.os == 'ubuntu-latest'
run: sudo apt install libasound2-dev -y

- name: Rust pre-build
run: bash copy.sh
working-directory: binding/rust

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Rust build demo
run: cargo build --verbose

- name: Test
run: cargo run --release -- --show_audio_devices

build-self-hosted:
runs-on: ${{ matrix.machine }}

strategy:
matrix:
machine: [rpi3-32, rpi3-64, rpi4-32, rpi4-64, beaglebone, jetson]

steps:
- uses: actions/checkout@v3

- name: Rust pre-build
run: bash copy.sh
working-directory: binding/rust

- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Rust build demo
run: cargo build --verbose

- name: Test
run: cargo run --release -- --show_audio_devices
27 changes: 19 additions & 8 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,25 @@ env:

defaults:
run:
working-directory: sdk/rust
shell: bash
working-directory: binding/rust

jobs:
build-github-hosted:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
os: [ubuntu-latest, macos-latest]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Rust dependencies
if: matrix.os == 'ubuntu-latest'
run: sudo apt install libasound2-dev -y

- name: Rust pre-build
run: bash copy.sh

Expand All @@ -61,24 +64,32 @@ jobs:
- name: Build
run: cargo build --verbose

- name: Run get audio devices
run: cargo run --release --example demo -- --show_audio_devices
- name: Test
run: cargo test --release

build-self-hosted:
runs-on: ${{ matrix.machine }}

strategy:
matrix:
machine: [rpi2, rpi3-32, rpi3-64, rpi4-32, rpi4-64, jetson, beaglebone]
machine: [rpi2, rpi3-32, rpi3-64, rpi4-32, rpi4-64, jetson, beaglebone, pv-windows]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Rust pre-build
if: matrix.machine != 'pv-windows'
run: bash copy.sh

- name: Rust pre-build windows
if: matrix.machine == 'pv-windows'
run: |
New-Item -Path "." -Name "data" -ItemType "directory"
New-Item -Path ".\data" -Name "lib" -ItemType "directory"
Copy-Item -Path "..\..\lib\windows" -Destination ".\data\lib" -Recurse
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
Expand All @@ -88,5 +99,5 @@ jobs:
- name: Build
run: cargo build --verbose

- name: Run get audio devices
run: cargo run --release --example demo -- --show_audio_devices
- name: Test
run: cargo test --release
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ For more information about NodeJS demos go to [demo/nodejs](demo/nodejs/).

### Rust Demo

Make sure there is a working microphone connected to your device. From [demo/rust/](demo/rust) run the following in the terminal to build and run the demo:

```console
cargo run --release -- --output_wav_path ${OUTPUT_WAV_PATH}
```

For more information about the Rust demo go to [demo/rust](demo/rust).

### C Demo

Run the following commands to build the demo app:
Expand Down Expand Up @@ -322,3 +330,34 @@ recorder.release();

### Rust

Add `pv_recorder` to your app's `Cargo.toml` manifest:

```toml
[dependencies]
pv_recorder = "*"
```

To start recording initialize the instance and run `start`:

```rust
use pv_recorder::PvRecorderBuilder

let frame_length = 512;
let recorder = PvRecorderBuilder::new(frame_length).init()?;
recorder.start()?;
```

Get a frame of audio by calling the read function:

```rust
while recorder.is_recording() {
let frame = recorder.read()?;
// do something with frame
}
```

To stop recording, run stop on the instance:

```rust
recorder.stop()?;
```
9 changes: 2 additions & 7 deletions binding/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pv_recorder"
version = "1.1.2"
version = "1.2.0"
edition = "2018"
description = "Rust recorder library for Picovoice"
license = "Apache-2.0"
Expand All @@ -26,9 +26,4 @@ crate_type = ["lib"]

[dependencies]
libc = "0.2"
libloading = "0.7"

[dev-dependencies]
hound = "3.4.0"
clap = "2.33.3"
ctrlc = "3.1.9"
libloading = "0.8"
53 changes: 15 additions & 38 deletions binding/rust/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# PvRecorder Rust Binding

A cross platform audio recorder that captures single-channel audio at a sample rate of 16kHz.
# PvRecorder Binding for Python

## Requirements

- Rust 1.54+

## Compatibility

- Windows (x86_64)
- macOS (x86_64)
- Linux (x86_64)
- macOS (x86_64 and arm64)
- Windows (x86_64)
- Raspberry Pi:
- Zero
- 2
Expand All @@ -32,27 +30,27 @@ pv_recorder = "*"
Getting the list of input devices does not require an instance:

```rust
use pv_recorder::RecorderBuilder
use pv_recorder::PvRecorderBuilder

let audio_devices = RecorderBuilder::default().get_audio_devices()?;
let audio_devices = PvRecorderBuilder::default().get_audio_devices()?;
```

To start recording initialize an instance using the builder and run `start`:

```rust
use pv_recorder::RecorderBuilder;
use pv_recorder::PvRecorderBuilder;

let recorder = RecorderBuilder::new().init()?;
let frame_length = 512;
let recorder = PvRecorderBuilder::new(frame_length).init()?;
recorder.start()?
```

Get the pcm frames by calling the read function:
Get frame of audio by calling the `read()` function:

```rust
loop {
let mut pcm_frame_buffer: [i16; FRAME_LENGTH] = [0; FRAME_LENGTH];
recorder.read(&mut pcm_frame_buffer)?;
// do something with pcm
while recorder.is_recording() {
let frame = recorder.read()?;
// process audio frame
}
```

Expand All @@ -62,28 +60,7 @@ To stop recording just run stop on the instance:
recorder.stop()?;
```

### Demo

For more detailed information on how to use the pv_recorder Rust sdk, see [examples/demo.rs](../../demo/rust/demo.rs).

In the following instructions, we will refer to `{AUDIO_DEVICE_INDEX}` as the index of the audio device to use, and `{OUTPUT_PATH}` as the path to save the raw audio data

`{AUDIO_DEVICE_INDEX}` defaults to -1 and `{OUTPUT_PATH}` can be empty if you wish to not save any data.

To show the available audio devices run:

```console
cargo run --release --example demo -- --show_audio_devices
```

To run the audio recorder:
## Demo

```console
cargo run --release --example demo -- --audio_device_index {AUDIO_DEVICE_INDEX} --output_path {OUTPUT_PATH}
```

See additional options by calling `-h/--help`:

```console
cargo run --release --example demo -- -h
```
The [PvRecorder Rust demo](https://github.com/Picovoice/pvrecorder/tree/main/demo/rust) is a Rust command-line application that demonstrates how to
use PvRecorder to record audio to a file.
Loading

0 comments on commit 8641b24

Please sign in to comment.