mirror of
https://github.com/lightsoutgames/bevy_tts.git
synced 2025-04-19 22:45:56 +00:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
a6c22b4eb0 | |||
a1c7c48003 | |||
3891f289d8 | |||
0ef7579f91 | |||
5c682ce6ee | |||
8d45d0a804 | |||
66c1522576 | |||
7fbf5f12f0 | |||
a6de8e190c | |||
7ad2070fa9 | |||
3ef32f30b9 | |||
947144357c | |||
4eab6322f7 | |||
8ac16ee97a | |||
a69ff429a7 | |||
50737584e0 | |||
80eaf43285 | |||
8cdcbaa38e | |||
cf585c6481 | |||
886b2f54e5 | |||
e9eb6767c6 | |||
56aafb389f | |||
9172c5020b | |||
a212d0cb9d | |||
1170961c38 | |||
14607d76a4 | |||
cac001d196 | |||
6cee04fb63 | |||
d362d8c171 | |||
2191d22f55 | |||
0924296361 | |||
c6c1ac197a | |||
0d3239b617 | |||
d3852b0159 | |||
e40a361960 | |||
49687ca4f3 | |||
f2cd47f2fe | |||
10be842598 | |||
678c56bfad | |||
d4a375215b | |||
4117b3dd34 | |||
21dd21fa5c | |||
6c68c5d193 | |||
a9dafc3309 | |||
4d39402860 | |||
6318858eed | |||
cde5938723 | |||
7e8a3c0e93 |
40
.drone.yml
40
.drone.yml
|
@ -1,40 +0,0 @@
|
|||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: rust
|
||||
commands:
|
||||
- rustup component add clippy rustfmt
|
||||
- apt-get update -qq
|
||||
- apt-get install -qqy llvm-dev libclang-dev clang libspeechd-dev pkg-config libx11-dev libasound2-dev libudev-dev libxcb-xfixes0-dev libwayland-dev libxkbcommon-dev libvulkan-dev libpulse-dev
|
||||
- cargo fmt --check
|
||||
- cargo test
|
||||
- cargo clippy
|
||||
- name: release
|
||||
image: rust
|
||||
commands:
|
||||
- cargo publish
|
||||
when:
|
||||
ref:
|
||||
- refs/tags/v*
|
||||
environment:
|
||||
CARGO_REGISTRY_TOKEN:
|
||||
from_secret: cargo_registry_token
|
||||
- name: discord notification
|
||||
image: appleboy/drone-discord
|
||||
when:
|
||||
status: [success, failure]
|
||||
settings:
|
||||
webhook_id:
|
||||
from_secret: discord_webhook_id
|
||||
webhook_token:
|
||||
from_secret: discord_webhook_token
|
||||
tts: true
|
||||
message: >
|
||||
{{#success build.status}}
|
||||
{{repo.name}} build {{build.number}} succeeded: <{{build.link}}>
|
||||
{{else}}
|
||||
{{repo.name}} build {{build.number}} failed: <{{build.link}}>
|
||||
{{/success}}
|
39
.gitea/workflows/release.yml
Normal file
39
.gitea/workflows/release.yml
Normal file
|
@ -0,0 +1,39 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
- name: install Linux build dependencies
|
||||
run: sudo apt-get update; sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev libwayland-dev libclang-dev libspeechd-dev
|
||||
if: runner.os == 'linux'
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
- name: Publish
|
||||
run: cargo publish
|
||||
env:
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
37
.gitea/workflows/test.yml
Normal file
37
.gitea/workflows/test.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
# os: [windows-latest, ubuntu-latest, macos-latest]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
- name: install Linux build dependencies
|
||||
run: sudo apt-get update; sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev libwayland-dev libclang-dev libspeechd-dev
|
||||
if: runner.os == 'linux'
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: pre-commit/action@v3.0.1
|
105
.github/workflows/release.yml
vendored
105
.github/workflows/release.yml
vendored
|
@ -1,105 +0,0 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: sudo apt-get update; sudo apt-get install -y libspeechd-dev
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all-features --examples
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --all-features
|
||||
|
||||
check_web:
|
||||
name: Check Web
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all-features --examples --target wasm32-unknown-unknown
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --all-features --target wasm32-unknown-unknown
|
||||
|
||||
publish_winrt_bindings:
|
||||
name: Publish winrt_bindings
|
||||
runs-on: windows-latest
|
||||
needs: [check]
|
||||
env:
|
||||
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
override: true
|
||||
- run: |
|
||||
cargo login $CARGO_TOKEN
|
||||
cd winrt_bindings
|
||||
cargo publish || true
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check, check_web]
|
||||
env:
|
||||
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libspeechd-dev
|
||||
cargo login $CARGO_TOKEN
|
||||
cargo publish
|
50
.github/workflows/test.yml
vendored
50
.github/workflows/test.yml
vendored
|
@ -1,50 +0,0 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libspeechd-dev pkg-config libx11-dev libasound2-dev libudev-dev
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
components: rustfmt, clippy
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all-features --examples
|
||||
if: ${{ runner.os != 'Linux' }}
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --no-default-features --examples
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all --check
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --all-features
|
||||
if: ${{ runner.os != 'Linux' }}
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --no-default-features
|
||||
if: ${{ runner.os == 'Linux' }}
|
10
.pre-commit-config.yaml
Normal file
10
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,10 @@
|
|||
fail_fast: true
|
||||
repos:
|
||||
- repo: https://github.com/doublify/pre-commit-rust
|
||||
rev: v1.0
|
||||
hooks:
|
||||
- id: fmt
|
||||
args: [--, --check]
|
||||
- id: cargo-check
|
||||
args: [--bins, --examples]
|
||||
- id: clippy
|
82
CHANGELOG.md
82
CHANGELOG.md
|
@ -2,6 +2,88 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Version 0.10.0 - 2024-12-05
|
||||
|
||||
### Features
|
||||
|
||||
- `Tts` can now be used as a component, and multiple TTS instances are supported.
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Upgrade to Bevy 0.15.
|
||||
|
||||
## Version 0.9.0 - 2024-07-07
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Switch to Gitea Actions.
|
||||
- Integrate pre-commit.
|
||||
- Update to Bevy 0.14.
|
||||
|
||||
## Version 0.8.0 - 2024-03-14
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Upgrade to Bevy v0.13.
|
||||
|
||||
## Version 0.7.0 - 2024-02-09
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Bump dependencies.
|
||||
|
||||
## Version 0.6.0 - 2023-07-16
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update to Bevy 0.11.
|
||||
|
||||
## Version 0.5.0 - 2023-03-06
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update Bevy to 0.10.
|
||||
|
||||
## Version 0.4.0 - 2022-12-20
|
||||
|
||||
### Features
|
||||
|
||||
- Make wrapped `Tts` instance public.
|
||||
|
||||
## Version 0.3.0 - 2022-12-20
|
||||
|
||||
### Features
|
||||
|
||||
- Add `Tts::screen_reader_available()` to `Tts` resource.
|
||||
|
||||
## Version 0.2.1 - 2022-12-20
|
||||
|
||||
### Features
|
||||
|
||||
- Re-export top-level `tts` crate.
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Always pull Rust image when building in CI.
|
||||
|
||||
## Version 0.2.0 - 2022-12-06
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update to Bevy 0.9 and TTS 0.25.
|
||||
|
||||
## Version 0.1.2 - 2022-09-07
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update tts dependency.
|
||||
|
||||
## Version 0.1.1 - 2022-08-29
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update automated build configuration to install dependencies on publish step.
|
||||
|
||||
## Version 0.1.0 - 2022-08-29
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
|
15
Cargo.toml
15
Cargo.toml
|
@ -1,8 +1,8 @@
|
|||
[package]
|
||||
name = "bevy_tts"
|
||||
version = "0.10.0"
|
||||
description = "Text-to-speech for the Bevy game engine"
|
||||
repository = "https://labs.lightsout.games/projects/bevy_tts"
|
||||
version = "0.1.0"
|
||||
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
|
@ -10,21 +10,22 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
default = ["speech_dispatcher_0_10_2", "tolk"]
|
||||
default = ["speech_dispatcher_0_11", "tolk"]
|
||||
speech_dispatcher_0_9 = ["tts/speech_dispatcher_0_9"]
|
||||
speech_dispatcher_0_10 = ["tts/speech_dispatcher_0_10"]
|
||||
speech_dispatcher_0_10_2 = ["tts/speech_dispatcher_0_10_2"]
|
||||
speech_dispatcher_0_11 = ["tts/speech_dispatcher_0_11"]
|
||||
tolk = ["tts/tolk"]
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.8", default-features = false }
|
||||
bevy = { version = "0.15", default-features = false }
|
||||
crossbeam-channel = "0.5"
|
||||
tts = { version = "0.23.1", default-features = false }
|
||||
tts = { version = "0.26", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
bevy = { version = "0.8", default-features = true }
|
||||
bevy = { version = "0.15", default-features = true }
|
||||
|
||||
[package.metadata.release]
|
||||
tag-prefix = ""
|
||||
publish = false
|
||||
push = false
|
||||
pre-release-hook = ["git-cliff", "-o", "CHANGELOG.md", "--tag", "{{version}}"]
|
||||
pre-release-commit-message = "Release"
|
||||
|
|
|
@ -3,17 +3,25 @@ use bevy_tts::*;
|
|||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugin(bevy_tts::TtsPlugin)
|
||||
.add_system(bevy::window::close_on_esc)
|
||||
.add_startup_system(setup)
|
||||
.add_system(event_poll)
|
||||
.add_system(greet)
|
||||
.add_plugins((DefaultPlugins, bevy_tts::TtsPlugin))
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, (event_poll, greet))
|
||||
.add_observer(|trigger: Trigger<TtsEvent>| {
|
||||
println!("{:?}", trigger.event());
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
// Speaks a bunch of messages and changes TTS properties.
|
||||
fn setup(mut tts: ResMut<Tts>) {
|
||||
fn setup(mut commands: Commands, mut tts: ResMut<Tts>) {
|
||||
let mut other_tts = Tts::default();
|
||||
let Features { voice, .. } = other_tts.supported_features();
|
||||
if voice {
|
||||
let voices = other_tts.voices().unwrap();
|
||||
let v = voices.last().unwrap();
|
||||
other_tts.set_voice(&v.clone()).unwrap();
|
||||
}
|
||||
commands.spawn(other_tts);
|
||||
tts.speak("Hello, world.", false).unwrap();
|
||||
let Features { rate, .. } = tts.supported_features();
|
||||
if rate {
|
||||
|
@ -60,18 +68,30 @@ fn setup(mut tts: ResMut<Tts>) {
|
|||
tts.set_volume(original_volume).unwrap();
|
||||
}
|
||||
tts.speak("Press G for a greeting.", false).unwrap();
|
||||
tts.speak(
|
||||
"Press S to speak with a second voice, if you're lucky.",
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Reports events from TTS subsystem.
|
||||
fn event_poll(mut events: EventReader<TtsEvent>) {
|
||||
for event in events.iter() {
|
||||
for event in events.read() {
|
||||
println!("{:?}", event);
|
||||
}
|
||||
}
|
||||
|
||||
// Shows how to output speech in response to a keypress.
|
||||
fn greet(input: Res<Input<KeyCode>>, mut tts: ResMut<Tts>) {
|
||||
if input.just_pressed(KeyCode::G) {
|
||||
fn greet(input: Res<ButtonInput<KeyCode>>, mut tts: ResMut<Tts>, mut speaker: Query<&mut Tts>) {
|
||||
if input.just_pressed(KeyCode::KeyG) {
|
||||
tts.speak("Hey there!", true).unwrap();
|
||||
}
|
||||
if input.just_pressed(KeyCode::KeyS) {
|
||||
if let Ok(mut speaker) = speaker.get_single_mut() {
|
||||
speaker
|
||||
.speak("Hey there from the TTS component!", true)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
102
src/lib.rs
102
src/lib.rs
|
@ -1,52 +1,96 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::{
|
||||
ecs::{component::ComponentId, world::DeferredWorld},
|
||||
prelude::*,
|
||||
};
|
||||
use crossbeam_channel::{unbounded, Receiver};
|
||||
pub use tts::{Backends, Error, Features, Tts, UtteranceId};
|
||||
pub use tts::{self, Backends, Error, Features, UtteranceId};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Component, Resource, Clone, Deref, DerefMut)]
|
||||
#[component(on_add = on_tts_added, on_remove=on_tts_removed)]
|
||||
pub struct Tts(pub tts::Tts);
|
||||
|
||||
impl Default for Tts {
|
||||
fn default() -> Self {
|
||||
Self(tts::Tts::default().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Tts {
|
||||
pub fn screen_reader_available() -> bool {
|
||||
tts::Tts::screen_reader_available()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Event, Debug)]
|
||||
pub enum TtsEvent {
|
||||
UtteranceBegin(UtteranceId),
|
||||
UtteranceEnd(UtteranceId),
|
||||
UtteranceStop(UtteranceId),
|
||||
}
|
||||
|
||||
#[derive(Component, Resource)]
|
||||
struct TtsChannel(Receiver<TtsEvent>);
|
||||
|
||||
fn poll_callbacks(channel: Res<TtsChannel>, mut events: EventWriter<TtsEvent>) {
|
||||
fn on_tts_added(mut world: DeferredWorld, entity: Entity, _: ComponentId) {
|
||||
let tts = &world.get::<Tts>(entity).unwrap();
|
||||
let channel = setup_tts(tts);
|
||||
world.commands().entity(entity).insert(channel);
|
||||
}
|
||||
|
||||
fn on_tts_removed(mut world: DeferredWorld, entity: Entity, _: ComponentId) {
|
||||
world.commands().entity(entity).remove::<TtsChannel>();
|
||||
}
|
||||
|
||||
fn poll_callbacks(
|
||||
mut commands: Commands,
|
||||
channel: Res<TtsChannel>,
|
||||
mut events: EventWriter<TtsEvent>,
|
||||
speakers: Query<(Entity, &TtsChannel), With<Tts>>,
|
||||
) {
|
||||
if let Ok(msg) = channel.0.try_recv() {
|
||||
events.send(msg);
|
||||
}
|
||||
for (entity, channel) in &speakers {
|
||||
if let Ok(msg) = channel.0.try_recv() {
|
||||
commands.entity(entity).trigger(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_tts(tts: &Tts) -> TtsChannel {
|
||||
let (tx, rx) = unbounded();
|
||||
let tx_begin = tx.clone();
|
||||
let tx_end = tx.clone();
|
||||
let tx_stop = tx;
|
||||
let Features {
|
||||
utterance_callbacks,
|
||||
..
|
||||
} = tts.supported_features();
|
||||
if utterance_callbacks {
|
||||
tts.on_utterance_begin(Some(Box::new(move |utterance| {
|
||||
tx_begin.send(TtsEvent::UtteranceBegin(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
tts.on_utterance_end(Some(Box::new(move |utterance| {
|
||||
tx_end.send(TtsEvent::UtteranceEnd(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
tts.on_utterance_stop(Some(Box::new(move |utterance| {
|
||||
tx_stop.send(TtsEvent::UtteranceStop(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
}
|
||||
TtsChannel(rx)
|
||||
}
|
||||
pub struct TtsPlugin;
|
||||
|
||||
impl Plugin for TtsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
let tts = Tts::default().unwrap();
|
||||
let (tx, rx) = unbounded();
|
||||
let tx_begin = tx.clone();
|
||||
let tx_end = tx.clone();
|
||||
let tx_stop = tx;
|
||||
let Features {
|
||||
utterance_callbacks,
|
||||
..
|
||||
} = tts.supported_features();
|
||||
if utterance_callbacks {
|
||||
tts.on_utterance_begin(Some(Box::new(move |utterance| {
|
||||
tx_begin.send(TtsEvent::UtteranceBegin(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
tts.on_utterance_end(Some(Box::new(move |utterance| {
|
||||
tx_end.send(TtsEvent::UtteranceEnd(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
tts.on_utterance_stop(Some(Box::new(move |utterance| {
|
||||
tx_stop.send(TtsEvent::UtteranceStop(utterance)).unwrap();
|
||||
})))
|
||||
.unwrap();
|
||||
}
|
||||
let tts = Tts::default();
|
||||
let channel = setup_tts(&tts);
|
||||
app.add_event::<TtsEvent>()
|
||||
.insert_resource(TtsChannel(rx))
|
||||
.insert_resource(channel)
|
||||
.insert_resource(tts)
|
||||
.add_system(poll_callbacks);
|
||||
.add_systems(Update, poll_callbacks);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user