diff --git a/Cargo.toml b/Cargo.toml index f2c2b83..cac8b7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,9 @@ keywords = ["time", "clock", "tui"] categories = ["date-and-time"] [features] -default = ["desktop"] +default = ["desktop", "sound"] desktop = ["dep:notify-rust"] +sound = ["dep:rodio", "desktop"] [dependencies] @@ -24,4 +25,5 @@ humantime = "2.1.0" libpt = { version = "0.6.0", features = ["cli"] } notify-rust = { version = "4.11.0", optional = true } ratatui = "0.27.0" +rodio = { version = "0.19.0", optional = true } tui-big-text = "0.4.5" diff --git a/README.md b/README.md index 0010af8..9bc9bf1 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,21 @@ A little clock for your terminal, written in rust. * [Original Repository](https://git.cscherr.de/PlexSheep/crock) * [GitHub Mirror](https://github.com/PlexSheep/crock) * [crates.io](https://crates.io/crates/crock) + +## Compilation + +The `desktop` and `sound` features require additional system dependencies: + +| Feature | Dependency | PKG Name on Debian based Distributions | +|-----------|------------|----------------------------------------| +| `desktop` | dbus | `libdbus-1-dev` | +| `sound` | alsa | `libasound2-dev` | + +If you want to compile without these features, you will not have notifications +and sound alerts for countdown mode. (Use `cargo build -r --no-default-features`) + +## Acknoledgements + +The included alarm sound is from pixabay, royalty free: + +-> ["Alarm Clock 1"](https://pixabay.com/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=105903) diff --git a/data/media/alarm.mp3 b/data/media/alarm.mp3 new file mode 100755 index 0000000..26d6c33 Binary files /dev/null and b/data/media/alarm.mp3 differ diff --git a/src/clock.rs b/src/clock.rs index 8194695..194c30b 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -13,7 +13,7 @@ use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use ratatui::style::{Style, Stylize}; use ratatui::widgets::{Block, LineGauge, Padding, Paragraph}; use ratatui::Terminal; -use std::io::{Stdout, Write}; +use std::io::{Cursor, Stdout, Write}; use std::time::{Duration, Instant}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -405,6 +405,21 @@ impl Clock { } fn notify(&mut self) -> anyhow::Result<()> { Self::beep()?; + #[cfg(feature = "sound")] + { + trace!("playing bundled sound"); + use rodio::{source::Source, Decoder, OutputStream}; + + // only 30 KiB, so let's just include it in the binary and not worry about reading it + // from the fs and somehow making the file be there + let sound: Cursor<_> = std::io::Cursor::new(include_bytes!("../data/media/alarm.mp3")); + + // Get an output stream handle to the default physical sound device + let (_stream, stream_handle) = OutputStream::try_default().unwrap(); + let source = Decoder::new(sound).expect("could not load the included sound"); + stream_handle.play_raw(source.convert_samples())?; // the sound plays in another thread + debug!("played bundled sound"); + } #[cfg(feature = "desktop")] { let mut notify = notify_rust::Notification::new(); @@ -420,6 +435,10 @@ impl Clock { // // TODO: add something to make a sound without the notification system, // as that is not reliable but the user might depend on it. + + // only play this when we don't use built in sound, this + // isn't as consistent + #[cfg(not(feature = "sound"))] notify.sound_name("alarm-clock-elapsed"); // The user sets the time with the expectation to be notified, but it's