diff --git a/demos/home-automation/rust/Cargo.toml b/demos/home-automation/rust/Cargo.toml index 18055886fc1..12501b48f7b 100644 --- a/demos/home-automation/rust/Cargo.toml +++ b/demos/home-automation/rust/Cargo.toml @@ -21,6 +21,7 @@ name = "home_automation_lib" [dependencies] slint = { path = "../../../api/rs/slint" } chrono = "0.4" +kira = "0.10" [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = { version = "0.2" } diff --git a/demos/home-automation/rust/lib.rs b/demos/home-automation/rust/lib.rs index b3ab0f932ef..f9cf2ebe29e 100644 --- a/demos/home-automation/rust/lib.rs +++ b/demos/home-automation/rust/lib.rs @@ -2,6 +2,11 @@ // SPDX-License-Identifier: MIT use chrono::{Datelike, Local, Timelike}; +use kira::{ + AudioManager, AudioManagerSettings, DefaultBackend, + sound::static_sound::StaticSoundData, +}; +use std::io::Cursor; use slint::{Timer, TimerMode}; #[cfg(target_arch = "wasm32")] @@ -11,6 +16,10 @@ slint::slint! { export { Api, AppWindow } from "../ui/demo.slint"; } +// https://sourceforge.net/projects/sox/ +// $ sox -n dial-tick.wav synth 0.01 sine 1000 fade t 0 0.01 0.005 gain -1 +const DIAL_TICK : &[u8] = include_bytes!("../ui/sounds/dial-tick.wav"); + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] pub fn main() { // This provides better error messages in debug mode. @@ -21,6 +30,18 @@ pub fn main() { let app = AppWindow::new().expect("AppWindow::new() failed"); let app_weak = app.as_weak(); + let mut manager = AudioManager::::new(AudioManagerSettings::default()).unwrap(); + + let api = app.global::(); + api.on_play_sound(move |sound| { + let sound = match sound { + SoundEffect::DialTick => DIAL_TICK, + }; + let cursor = Cursor::new(sound); + let sound_data = StaticSoundData::from_cursor(cursor).unwrap(); + let _sound_handle = manager.play(sound_data).unwrap(); + }); + let timer = Timer::default(); timer.start(TimerMode::Repeated, std::time::Duration::from_millis(1000), move || { if let Some(app) = app_weak.upgrade() { diff --git a/demos/home-automation/ui/api.slint b/demos/home-automation/ui/api.slint index 689bc72bc9c..cead973b00d 100644 --- a/demos/home-automation/ui/api.slint +++ b/demos/home-automation/ui/api.slint @@ -17,6 +17,10 @@ export struct WeatherData { temperature: float, } +export enum SoundEffect { + dial-tick, +} + export global Api { in property indoor-temperature: 22.0; in property outdoor-temperature: 24.0; @@ -95,4 +99,6 @@ export global Api { temperature: 23.0, }, ]; + + callback play-sound(SoundEffect); } diff --git a/demos/home-automation/ui/components/dial/dial.slint b/demos/home-automation/ui/components/dial/dial.slint index 36c1f6f12b0..ff0602655fe 100644 --- a/demos/home-automation/ui/components/dial/dial.slint +++ b/demos/home-automation/ui/components/dial/dial.slint @@ -1,6 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: MIT import { Palette } from "../../common.slint"; +import { Api, SoundEffect } from "../../api.slint"; export global DialState { out property totalLights: 60; @@ -19,6 +20,9 @@ export component Dial { property moving: ta.firstTouch; in-out property dialAngle: DialState.startAngle; out property volume: ((dialAngle - DialState.startAngle) / DialState.degreesFilledWithLights) * DialState.totalLights; + changed volume => { + Api.play-sound(SoundEffect.dial-tick); + } width: 212px; height: 213px; diff --git a/demos/home-automation/ui/sounds/dial-tick.wav b/demos/home-automation/ui/sounds/dial-tick.wav new file mode 100644 index 00000000000..979dd5bed01 Binary files /dev/null and b/demos/home-automation/ui/sounds/dial-tick.wav differ